如何获取函数抛出的错误列表?

时间:2016-01-19 12:37:21

标签: ios swift error-handling nserror

现在使用Swift,一些函数标有throws,这迫使开发人员在do - try catch块内调用该函数。 但是开发人员如何知道该函数抛出的不同异常列表?

作为参考,这是一行Java代码:

static void  employeeAge(int age) throws MyExceptionA,MyExceptionB

很明显,例外情况是2 MyExceptionAMyExceptionB,开发人员可以决定采取不同的行动,具体取决于错误。

我们可以在Swift上实现相同的目标吗?

3 个答案:

答案 0 :(得分:4)

当Swift文档说明函数throws时,它们意味着抛出ErrorType(在Cocoa API中通常为NSError),而不是例外。

考虑do-try-catch createDirectoryAtPath的以下NSFileManager流程:

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]

do {
    try NSFileManager.defaultManager().createDirectoryAtPath(documentsPath, withIntermediateDirectories: false, attributes: nil)
} catch { 
    // 'error' variable automatically populated
    print(error)
    print(error.dynamicType)
}

createDirectoryAtPath将失败,因为文档目录已存在。记录dynamicType的{​​{1}}表示它实际上是error个对象:

NSError

为了查看函数Error Domain=NSCocoaErrorDomain Code=516 "The file “Documents” couldn’t be saved in the folder “35B0B3BF-D502-4BA0-A991-D07568AB87C6” because a file with the same name already exists." UserInfo={NSFilePath=/Users/jal/Library/Developer/CoreSimulator/Devices/E8A35774-C9B7-42F0-93F1-8103FBBC7118/data/Containers/Data/Application/35B0B3BF-D502-4BA0-A991-D07568AB87C6/Documents, NSUnderlyingError=0x7fa88bd14410 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}} NSError 的不同类型的错误,您必须检查throw以获取信息,以确定抛出的错误类型以及如何处理每个错误。在error的情况下,这将是其域,代码和描述。

在这种特殊情况下,该路径上已存在目录,因此文件管理器无法创建新目录。此操作可能失败的另一个原因的示例是文件管理器没有写访问权限。那将是错误代码256。

答案 1 :(得分:1)

我和OP有完全相同的问题。因为没有人真正回答这个问题(我也是这样),这是我的贡献。

在Swift 3和Xcode 8.3.3中,您将按如下方式处理个别异常。下面我将以FileManager为例给出一个例子。

首先,您将只有一个catch块来捕获该方法抛出的任何错误。然后,您将该错误转换为NSError。与Swift中的Error协议相反,NSError是一个REAL错误类。然后,您可以在switch语句中提取该错误的代码。您必须知道该方法引发错误的域,然后在相应的头文件中找到错误代码。

在下面的示例中,NSCocoaErrorDomain中引发了与文件相关的错误,并且这些错误代码在Foundation / FoundationErrors.h中定义/列出。在我的电脑中,它们位于

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/FoundationErrors.h

用于macOS应用程序和

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/

适用于iPhone应用。

所以这是一个例子:

let home = FileManager.default.homeDirectoryForCurrentUser
let file = home.appendingPathComponent("file")
do {
    let loadedString = try String(contentsOf: file)
}
catch {
    let realError = error as NSError // As weird as it looks, Xcode actually wants this forced conversion
    print(realError.localizedDescription)
    switch realError.code {
    case 257: // No permission
        handleNoPermission()
    case 260: // File not found
        handleFileNotFound()
    default:
        handleUndefinedError()
    }
}

.localizedDescription在您的用户的语言中包含有关该错误的用户友好消息。如果在上面找不到文件,则以英文打印:The file “file” couldn’t be opened because there is no such file.。它可以直接在您向用户显示的错误对话框中使用。

您还可以在此处找到有关每个域引发的错误的更多信息:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html

答案 2 :(得分:-2)

您在catch之后编写一个模式,以指示该子句可以处理的错误。

do {
    try expression
    statements
} catch pattern 1 {
    statements
} catch pattern 2 where condition {
    statements
}

请参阅使用Swift Programming Language的Do-Catch处理错误