Swift CustomNSErrorを利用して、より詳しいエラー情報を定義する


概要

CustomNSError を使ってより詳細なエラーを定義します。

はじめに

Swiftでコーディングするとき、何かの失敗を表すときに Error を使うことがよくあるかと思います。

enum MyError: Error {
    case one
    case two
}

エラーを見て何が起こったかを調べて問題を解決していくことがあると思いますが、
例えば次の analyzeError のような、MyErrorに限らず何のエラーが来るかわからないError を引数に取った場合、一度NSError に変換することによってdomainやcodeなど、より詳しい情報を得ることが可能です。

enum MyError: Error {
    case one
    case two
}

func analyzeError(error: Error) {
    let nsError: NSError = error as NSError
    print(nsError.domain) // __lldb_expr_1.MyError
    print(nsError.code) // 0
    print(nsError.userInfo) // [:]
}

analyzeError(error: MyError.one)

このように、単なる Error を設定すると、domainおよびcodeは自動で決定され、userInfoには空の辞書が入っています。

CustomNSError

CustomNSError を使うと、domain、codeおよびuserInfoの定義が可能になります。
errorDomain はdomain、errorCode はcode、errorUserInfo はuserInfoとして表現されるようになります。

enum YourError: Error {
    case one
}

enum MyError: CustomNSError {
    case one([String : Any])
    case two

    var errorCode: Int {
        switch self {
        case .one:
            return 1
        case .two:
            return 2
        }
    }

    var errorUserInfo: [String: Any] {
        switch self {
        case .one(let userInfo):
            return userInfo
        case .two:
            return [:]
        }
    }

    static var errorDomain: String = "CustomMyError"
}

func analyzeError(error: Error) {
    let nsError: NSError = error as NSError
    print(nsError.domain) // CustomMyError
    print(nsError.code) // 1
    print(nsError.userInfo) // ["NSUnderlyingError": __lldb_expr_7.YourError.one]
}

analyzeError(error: MyError.one([NSUnderlyingErrorKey : YourError.one]))