如何找到方法可能抛出的错误类型并在 Swift 中捕获它们 [重复]

Posted

技术标签:

【中文标题】如何找到方法可能抛出的错误类型并在 Swift 中捕获它们 [重复]【英文标题】:How to find the kind of errors a method may throw and catch them in Swift [duplicate] 【发布时间】:2015-11-05 19:14:32 【问题描述】:

我正在使用NSFileManager.contentsOfDirectoryAtPath 来获取目录中的文件名数组。我想使用新的do-try-catch 语法来处理错误:

do 
    
    let docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)

 catch 
    
    // handle errors
    print(error) // this is the best I can currently do


我可以想象一个错误可能是docsPath 不存在,但我不知道如何捕捉这个错误。而且我不知道可能会发生什么其他错误。

文档示例

Error Handling documentation 有一个这样的例子

enum VendingMachineError: ErrorType 
    case InvalidSelection
    case InsufficientFunds(centsNeeded: Int)
    case OutOfStock

do 
    try vend(itemNamed: "Candy Bar")
    // Enjoy delicious snack
 catch VendingMachineError.InvalidSelection 
    print("Invalid Selection.")
 catch VendingMachineError.OutOfStock 
    print("Out of Stock.")
 catch VendingMachineError.InsufficientFunds(let amountNeeded) 
    print("Insufficient funds. Please insert an additional \(amountNeeded) cents.")

但我不知道如何做类似的事情来捕获具有使用 throws 关键字的方法的标准 Swift 类型的错误。

NSFileManager class reference for contentsOfDirectoryAtPath 没有说明可能会返回什么样的错误。所以我不知道要捕获什么错误,或者如果我得到它们如何处理它们。

更新

我想做这样的事情:

do 
    let docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)
 catch FileManagerError.PathNotFound 
    print("The path you selected does not exist.")
 catch FileManagerError.PermissionDenied 
    print("You do not have permission to access this directory.")
 catch ErrorType 
    print("An error occured.")

【问题讨论】:

重复? How get the list of errors thrown by a function? @JAL,是的,这个问题很相似。在您的回答中,您展示了如何获取NSError,但您没有提供有关如何区分和处理不同类型错误的任何详细信息。 也相关(参见 cmets 中的讨论):Find what errors a function can throw in Xcode with Swift 确实无法获得函数抛出的 ErrorTypes 列表。 ErrorType是一个枚举对象可以遵循的协议(NSError遵循ErrorType,具体错误需要查看返回的错误码)。 【参考方案1】:

NSError 自动桥接到 ErrorType,其中域变成类型(例如,NSCocoaErrorDomain 变成 CocoaError)并且错误代码变成值(NSFileReadNoSuchFileError 变成 .fileNoSuchFile

import Foundation

let docsPath = "/file/not/found"
let fileManager = FileManager()

do 
    let docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)
 catch CocoaError.fileNoSuchFile 
    print("No such file")
 catch let error 
    // other errors
    print(error.localizedDescription)

至于知道特定调用可以返回哪个错误,只有文档可以提供帮助。几乎所有 Foundation 错误都是 CocoaError 域的一部分,可以在 FoundationErrors.h 中找到(尽管有一些罕见的错误,Foundation 有时也会在 NSPOSIXErrorDomain 下返回 POSIX 错误)但这些错误可能还没有完全桥接,所以您将不得不在NSError 级别重新管理它们。

更多信息可以在« Using Swift with Cocoa and Objective-C (Swift 2.2) »找到

【讨论】:

对于 Swift 3+,您可以这样做: catch CocoaError.fileReadNoSuchFile ... 可捕获的 CocoaErrors 列表位于 developer.apple.com/documentation/foundation/cocoaerror【参考方案2】:

您在“更新”部分提出的问题是不可能的。 抛出函数决定让你知道它可能抛出什么,或者不显示它,然后你需要处理一个通用错误。

许多函数确实揭示了有关抛出错误的信息 - 例如:

func start***Tunnel() throws
Description 
Start the process of connecting the ***
true if the process of connecting the *** started successfully, false if an error occurred.
Parameters  
error   
A pointer to a pointer to an NSError object. If specified and the *** connection process cannot be started due to an error, this parameter will be set to point to an NSError object containing details about the error. See NE***Manager Class Reference for a list of possible errors.

编辑:一个可能的原因 - 就是这样,抛出函数可以改变它抛出的错误,并且所有捕获这些错误的代码仍然有效。

【讨论】:

【参考方案3】:

它会返回 NSError:

let fileManager = NSFileManager()

do 

    let docsArray = try fileManager.contentsOfDirectoryAtPath("/")

 catch let error as NSError 

    // handle errors
    print(error.localizedDescription)

    // The file “Macintosh HD” couldn’t be opened because you don’t have permission to view it.

【讨论】:

所以你是说自定义类的错误处理文档中没有枚举列表?我应该只打印错误给我的任何描述,而不是尝试根据错误类型进行个性化行为吗?如果我除了打印错误还想做点什么? 对。这仍然与您在 Obj-C 中看到的相同,如果您查看 Obj-C 文档,它使用 NSError,这与 Cocoa (Touch) 框架的其余部分非常一致。 NSError 是一个符合 ErrorType 的类。您可以做的不仅仅是打印描述,请参阅developer.apple.com/library/mac/documentation/Cocoa/Reference/…。 有没有办法像我在更新中展示的那样做?

以上是关于如何找到方法可能抛出的错误类型并在 Swift 中捕获它们 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在Swift 2中使用自定义消息抛出错误/异常的最简单方法?

如何检查 Jest 中异步抛出的错误类型?

Swift 2:从类型的抛出函数到非抛出函数的无效转换

学习Swift -- 错误处理

当抛出的任何错误都没有冒泡时,如何在 Promise 中进行断言?

如何解决在Angular 6中为业力测试抛出的[object ErrorEvent]