LoginSignup
17
16

エラー処理の基本の理解を深めよう!

Last updated at Posted at 2024-02-16

エラー処理

エラー処理は、プログラムのエラー状態に応答し、エラー状態から回復するプロセスのことである!
アプリ操作が失敗してエラーになった場合、コードがそれに応じて応答できるようにすることで、失敗の原因を確認、エラー復旧することが可能になる!

エラーの表現

エラーはErrorプロトコルに準拠した型によって表される!

enum APIClientError: Error {
    case networkError
}

throw文

エラーを投げるには、throw文を使用する!
throw文は、任意のタイミングでエラーを発生させるときに使用する!throw文でエラーを投げるためには、Errorプロトコルに準拠させる必要がる!

switch (response as? HTTPURLResponse)?.statusCode {
        case 200:
            let weatherData = try JSONDecoder().decode(WeatherData.self, from: data)
            let description = weatherData.weather[0].main
            let cityName = weatherData.name
            return (description, cityName)
        default:
            throw APIClientError.networkError
        }

上記はAPI通信の結果であるresponse200 OKじゃなければエラーを投げる処理。

throwsキーワードを使用した関数によるエラー処理

関数・メソッド・イニシャライザがエラーを投げる可能性があることを示すには、関数の宣言のパラメータの後にthrowsキーワードを記述する。
throwsでマークされた関数は、スロー関数と呼ばれる。
関数が戻り値の型を指定する戻り矢印(->)の前にthrowsキーワードを記述する。
そうすると、Stringのタプル or Errorを返す関数になる!

func getWeather(latitude: String, longitude: String) async throws -> (String, String) {
        let urlString = "https://api.openweathermap.org/data/2.5/weather?lat=\(latitude)&lon=\(longitude)&appid=\(Constants.apiKey)"
        let url = URL(string: urlString)
        let urlRequest = URLRequest(url: url!)
        let (data, response) = try await URLSession.shared.data(for: urlRequest)
        switch (response as? HTTPURLResponse)?.statusCode {
        case 200:
            let weatherData = try JSONDecoder().decode(WeatherData.self, from: data)
            let description = weatherData.weather[0].main
            let cityName = weatherData.name
            return (description, cityName)
        default:
            throw APIClientError.networkError
        }
    }

do-catch文を使用したエラー処理

do-catch文は、次のようにdoを宣言し、正常時に実行したいコードを記述する。catchには、エラー時に実行したいコードを記述する。do節の実行中にエラーが発生すると、catch節に実行が移る。
呼び出す側はエラーを返す可能性のあるメソッドをtryキーワードを使用し、呼び出す!

private func showWeatherView() {
        let (latitude, longitude) = PrefectureLatLon().fetchLatLon(weatherPrefecture: prefecture)
        Task { @MainActor in
            do {
                let (description, cityName) = try await WeatherAPIClient().getWeather(latitude: latitude, longitude: longitude)
                self.weatherLabel.text = description
                self.prefectureLabel.text = cityName
            } catch {
                let alert = AlertMaker().make(didTapRetry: {
                    self.showWeatherView()
                })
                self.present(alert, animated: true, completion: nil)
            }
        }
    }

正常にAPI通信が実行できるとdo{}内の処理が実行され、ViewにAPIから取得した天気と地域を表示する!
エラーが発生するとcatch{}内の処理が実行され、アラートを表示する!

おまけ: async/awaitについて知りたい方はこちら

参考文献

17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16