サーチ…


備考

エラーの詳細については、Swiftプログラミング言語を参照してください。

エラー処理の基本

Swiftの関数は、値を返したり、 エラーを投げたり、あるいはその両方を返します。

func reticulateSplines()                // no return value and no error
func reticulateSplines() -> Int         // always returns a value
func reticulateSplines() throws         // no return value, but may throw an error
func reticulateSplines() throws -> Int  // may either return a value or throw an error

ErrorTypeプロトコル (NSErrorオブジェクトを含む)に準拠する値は、エラーとしてスローされる可能性があります。 列挙は、カスタムエラーを定義する便利な方法を提供します。

2.0 2.2
enum NetworkError: ErrorType {
    case Offline
    case ServerError(String)
}
3.0
enum NetworkError: Error {
    // Swift 3 dictates that enum cases should be `lowerCamelCase`
    case offline
    case serverError(String)
}

エラーは、プログラムの実行中に致命的ではない障害を示し、特殊な制御フロー構造do / catchthrowtryます。

func fetchResource(resource: NSURL) throws -> String {
    if let (statusCode, responseString) = /* ...from elsewhere...*/ {
        if case 500..<600 = statusCode {
            throw NetworkError.serverError(responseString)
        } else {
            return responseString
        }
    } else {
        throw NetworkError.offline
    }
}

do / catchでエラーを捕らえることができます:

do {
    let response = try fetchResource(resURL)
    // If fetchResource() didn't throw an error, execution continues here:
    print("Got response: \(response)")
    ...
} catch {
    // If an error is thrown, we can handle it here.
    print("Whoops, couldn't fetch resource: \(error)")
}

tryを使ってエラーを投げる可能性のある関数を呼び出す必要ありますtry? 、またはtry!

// error: call can throw but is not marked with 'try'
let response = fetchResource(resURL)

// "try" works within do/catch, or within another throwing function:
do {
    let response = try fetchResource(resURL)
} catch {
    // Handle the error
}

func foo() throws {
    // If an error is thrown, continue passing it up to the caller.
    let response = try fetchResource(resURL)
}

// "try?" wraps the function's return value in an Optional (nil if an error was thrown).
if let response = try? fetchResource(resURL) {
    // no error was thrown
}

// "try!" crashes the program at runtime if an error occurs.
let response = try! fetchResource(resURL)

異なるエラータイプをキャッチする

この例では独自のエラータイプを作成しましょう。

2.2
enum CustomError: ErrorType {
    case SomeError
    case AnotherError
}

func throwing() throws {
    throw CustomError.SomeError
}
3.0
enum CustomError: Error {
    case someError
    case anotherError
}

func throwing() throws {
    throw CustomError.someError
}

Do-Catch構文は、スローされたエラーをキャッチすることを可能にし、 catchブロックで利用可能なerrorという名前の定数を自動的に作成します。

do {
    try throwing()
} catch {
    print(error)
}

自分で変数を宣言することもできます:

do {
    try throwing()
} catch let oops {
    print(oops)
}

また、異なるcatch文を連鎖させることもできます。これは、Doブロックにいくつかのタイプのエラーがスローされる場合に便利です。

ここでDo-Catchは最初にCustomErrorとしてエラーをキャストしようとしますが、カスタムタイプが一致しなかった場合はNSErrorとしてキャストしようとします。

2.2
do {
    try somethingMayThrow()
} catch let custom as CustomError {
    print(custom)
} catch let error as NSError {
    print(error)
}
3.0

Swift 3では、NSErrorに明示的にダウンキャストする必要はありません。

do {
    try somethingMayThrow()
} catch let custom as CustomError {
    print(custom)
} catch {
    print(error)
}

明示的なエラー処理のためのキャッチとスイッチパターン

class Plane {
    
    enum Emergency: ErrorType {
        case NoFuel
        case EngineFailure(reason: String)
        case DamagedWing
    }

    var fuelInKilograms: Int

    //... init and other methods not shown

    func fly() throws {
        // ...
        if fuelInKilograms <= 0 {
            // uh oh...
            throw Emergency.NoFuel
        }
    }

}

クライアントクラス:

let airforceOne = Plane()
do {
    try airforceOne.fly()
} catch let emergency as Plane.Emergency {
    switch emergency {
    case .NoFuel:
        // call nearest airport for emergency landing
    case .EngineFailure(let reason):
        print(reason) // let the mechanic know the reason
    case .DamagedWing:
        // Assess the damage and determine if the president can make it
    }
}

エラー伝播を無効にする

Swiftのクリエイターは、表現力豊かな表現に多くの関心を寄せています。エラー処理は、表現力豊かなものです。エラーをスローする関数を呼び出そうとすると、関数呼び出しの前にtryキーワードが必要です。 tryキーワードは魔法ではありません。それは、開発者が関数の投げ込み能力を認識できるようにすることです。

たとえば、次のコードでは、指定されたパスでイメージリソースをロードするloadImage(atPath :)関数を使用します。イメージをロードできない場合はエラーをスローします。この場合、イメージはアプリケーションと共に出荷されるため、実行時にエラーはスローされないため、エラー伝播を無効にすることが適切です。

let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")

ローカライズされた説明でカスタムエラーを作成する

enumのカスタムエラーを作成する

enum RegistrationError: Error {
    case invalidEmail
    case invalidPassword
    case invalidPhoneNumber
}

ローカライズされた説明を処理するためのRegistrationError extensionを作成します。

extension RegistrationError: LocalizedError {
    public var errorDescription: String? {
        switch self {
        case .invalidEmail:
            return NSLocalizedString("Description of invalid email address", comment: "Invalid Email")
        case .invalidPassword:
            return NSLocalizedString("Description of invalid password", comment: "Invalid Password")
        case .invalidPhoneNumber:
            return NSLocalizedString("Description of invalid phoneNumber", comment: "Invalid Phone Number")
        }
    }
}

ハンドルエラー:

let error: Error = RegistrationError.invalidEmail
print(error.localizedDescription)


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow