如何从 NSError 代码中找到错误描述?

问题描述 投票:0回答:4

我正在尝试找到一种比 Google 搜索更简单/更可靠的方法来从错误代码中找出 NSError 的本地化描述。

例如,我知道 NSURLErrorDomain 代码 -1003 对应于“无法找到具有指定主机名的服务器”。但如果我尝试在代码中验证它,它不匹配。

let error = NSError(domain: "NSURLErrorDomain", code: -1003)
print(error.localizedDescription)
// "The operation couldn’t be completed. (NSURLErrorDomain error -1003.)"

documentation 中查找 -1003 也不匹配:“无法解析 URL 的主机名。”

因此,我正在寻找一种方法来从带有函数的错误代码中找出描述,或者从具有我期望的描述的文档中找出描述。我希望有一个类似于

HTTPURLResponse.localizedString(forStatusCode:)

的功能
ios nserror nsurlerrordomain
4个回答
6
投票

当您像这样创建自己的

NSError
对象时,不会为您生成
localizedDescription
。但是,当
URLSession
生成错误对象时,会填充本地化描述:

let url = URL(string: "https://bad.domain")!
URLSession.shared.dataTask(with: url) { data, response, error in
    if let error = error as? URLError {
        print(error.localizedDescription)  // “A server with the specified hostname could not be found.”
    }
}.resume()

因此,如果您遇到错误并想查看本地化描述,请这样做。如果您手动创建自己的

NSError
对象,它根本不起作用。

但一般来说,我们不会担心本地化描述,而是测试

code
 的各种 
URLError
值,寻找
code
.cannotFindHost
:

let url = URL(string: "https://bad.domain")!
URLSession.shared.dataTask(with: url) { data, response, error in
    if let error = error as? URLError {
        switch error.code {
        case .cannotFindHost: print("cannotFindHost")
        case .cancelled:      print("cancelled")
        case .badURL:         print("badURL")
        // ...
        default:              break
        }
    }
}.resume()

或者,您也可以使用

NSURLError
搜索旧的
NSError
代码值,寻找
NSURLErrorCannotFindHost
:

URLSession.shared.dataTask(with: url) { data, response, error in
    if let error = error as NSError? {
        switch error.code {
        case NSURLErrorCannotFindHost: print("cannotFindHost")
        case NSURLErrorCancelled:      print("cancelled")
        case NSURLErrorBadURL:         print("badURL")
        // ...
        default:                       break
        }
    }
}.resume()

您也可以通过按shift-命令-O(字母“Oh”)来“快速打开”,搜索

NSURLError
,取消勾选快速打开右上角的“Swift”按钮对话:

enter image description here

当您打开

NSURLError.h
文件时,您可以看到其中列出的所有代码。

但是,不,仅通过使用指定的域和代码创建

NSError
localizedDescription
不会神奇地为您填充。不过,
URLSession
创建了带有描述的正确错误对象。


1
投票

不,大多数事情都没有自动查找(有使用 SecCopyErrorMessageString 的安全错误,但一般情况下不是)。您必须检查标题。这是在 NSURLError.h 中:

NSURLErrorCannotFindHost =          -1003,

通常,您要查找的字符串将位于 NSError 的 userInfo 中,并由生成错误的事物放置在那里。它不会从代码中查找到。当 userInfo 中没有消息时,

localizedDescription
默认是写“操作无法完成...”

我不相信有任何内置方法可以生成“像系统那样”的错误。 (这非常依赖于子系统,因为 URLErrors 有很多需要填写的键,这些键不适用于其他类型的错误。)


0
投票

各位,我想添加此链接供其他人在尝试识别特定错误代码号时参考。 GitHub 上的 Swift.org 开源项目提供的错误代码


0
投票

您可以对

URLError.Code
进行以下扩展,以便从 URLError.Code 获取可读的原因。

extension URLError.Code: CustomDebugStringConvertible {
    public var debugDescription: String {
        switch self {
        case .unknown:
            "URLError.Code.unknown: \(rawValue)"
        case .cancelled:
            "URLError.Code.cancelled: \(rawValue)"
        case .badURL:
            "URLError.Code.badURL: \(rawValue)"
        case .timedOut:
            "URLError.Code.timedOut: \(rawValue)"
        case .unsupportedURL:
            "URLError.Code.unsupportedURL: \(rawValue)"
        case .cannotFindHost:
            "URLError.Code.cannotFindHost: \(rawValue)"
        case .cannotConnectToHost:
            "URLError.Code.cannotConnectToHost: \(rawValue)"
        case .networkConnectionLost:
            "URLError.Code.networkConnectionLost: \(rawValue)"
        case .dnsLookupFailed:
            "URLError.Code.dnsLookupFailed: \(rawValue)"
        case .httpTooManyRedirects:
            "URLError.Code.httpTooManyRedirects: \(rawValue)"
        case .resourceUnavailable:
            "URLError.Code.resourceUnavailable: \(rawValue)"
        case .notConnectedToInternet:
            "URLError.Code.notConnectedToInternet: \(rawValue)"
        case .redirectToNonExistentLocation:
            "URLError.Code.redirectToNonExistentLocation: \(rawValue)"
        case .badServerResponse:
            "URLError.Code.badServerResponse: \(rawValue)"
        case .userCancelledAuthentication:
            "URLError.Code.userCancelledAuthentication: \(rawValue)"
        case .userAuthenticationRequired:
            "URLError.Code.userAuthenticationRequired: \(rawValue)"
        case .zeroByteResource:
            "URLError.Code.zeroByteResource: \(rawValue)"
        case .cannotDecodeRawData:
            "URLError.Code.cannotDecodeRawData: \(rawValue)"
        case .cannotDecodeContentData:
            "URLError.Code.cannotDecodeContentData: \(rawValue)"
        case .cannotParseResponse:
            "URLError.Code.cannotParseResponse: \(rawValue)"
        case .appTransportSecurityRequiresSecureConnection:
            "URLError.Code.appTransportSecurityRequiresSecureConnection: \(rawValue)"
        case .fileDoesNotExist:
            "URLError.Code.fileDoesNotExist: \(rawValue)"
        case .fileIsDirectory:
            "URLError.Code.fileIsDirectory: \(rawValue)"
        case .noPermissionsToReadFile:
            "URLError.Code.noPermissionsToReadFile: \(rawValue)"
        case .dataLengthExceedsMaximum:
            "URLError.Code.dataLengthExceedsMaximum: \(rawValue)"
        case .secureConnectionFailed:
            "URLError.Code.secureConnectionFailed: \(rawValue)"
        case .serverCertificateHasBadDate:
            "URLError.Code.serverCertificateHasBadDate: \(rawValue)"
        case .serverCertificateUntrusted:
            "URLError.Code.serverCertificateUntrusted: \(rawValue)"
        case .serverCertificateHasUnknownRoot:
            "URLError.Code.serverCertificateHasUnknownRoot: \(rawValue)"
        case .serverCertificateNotYetValid:
            "URLError.Code.serverCertificateNotYetValid: \(rawValue)"
        case .clientCertificateRejected:
            "URLError.Code.clientCertificateRejected: \(rawValue)"
        case .clientCertificateRequired:
            "URLError.Code.clientCertificateRequired: \(rawValue)"
        case .cannotLoadFromNetwork:
            "URLError.Code.cannotLoadFromNetwork: \(rawValue)"
        case .cannotCreateFile:
            "URLError.Code.cannotCreateFile: \(rawValue)"
        case .cannotOpenFile:
            "URLError.Code.cannotOpenFile: \(rawValue)"
        case .cannotCloseFile:
            "URLError.Code.cannotCloseFile: \(rawValue)"
        case .cannotWriteToFile:
            "URLError.Code.cannotWriteToFile: \(rawValue)"
        case .cannotRemoveFile:
            "URLError.Code.cannotRemoveFile: \(rawValue)"
        case .cannotMoveFile:
            "URLError.Code.cannotMoveFile: \(rawValue)"
        case .downloadDecodingFailedMidStream:
            "URLError.Code.downloadDecodingFailedMidStream: \(rawValue)"
        case .downloadDecodingFailedToComplete:
            "URLError.Code.downloadDecodingFailedToComplete: \(rawValue)"
        case .internationalRoamingOff:
            "URLError.Code.internationalRoamingOff: \(rawValue)"
        case .callIsActive:
            "URLError.Code.callIsActive: \(rawValue)"
        case .dataNotAllowed:
            "URLError.Code.dataNotAllowed: \(rawValue)"
        case .requestBodyStreamExhausted:
            "URLError.Code.requestBodyStreamExhausted: \(rawValue)"
        case .backgroundSessionRequiresSharedContainer:
            "URLError.Code.backgroundSessionRequiresSharedContainer: \(rawValue)"
        case .backgroundSessionInUseByAnotherProcess:
            "URLError.Code.backgroundSessionInUseByAnotherProcess: \(rawValue)"
        case .backgroundSessionWasDisconnected:
            "URLError.Code.backgroundSessionWasDisconnected: \(rawValue)"
        default:
            "URLError.Code.unknownError: \(rawValue)"
        }
    }
}

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.