我正在寻找一种方法来捕捉catch
中的多种类型的错误。我尝试了fallthrough
和逗号分隔的样式与switch语句,但都不起作用。 docs对删除多个pattern 1
没有任何说法。我不清楚哪种模式语法可以在这里工作。
错误定义(示例):
enum AppErrors {
case NotFound(objectType: String, id: Int)
case AlreadyUsed
}
使用:
do {
//...
} catch AppErrors.NotFound {
makeNewOne()
} catch AppErrors.AlreadyUsed {
makeNewOne()
} catch {
print("Unhandled error: \(error)")
}
不编译,是否可以做这样的事情?
do {
//...
} catch AppErrors.NotFound, AppErrors.AlreadyUsed {
makeNewOne()
} catch {
print("Unhandled error: \(error)")
}
答案 0 :(得分:10)
如果要捕获所有AppErrors
,可以使用此模式:
catch is AppErrors
如果你正在寻找更具体的匹配,它似乎很快变得难看。
这将让我们抓住AppErrors
的具体案例:
catch let error as AppErrors where error == .NotFound || error == .AlreadyUsed
这种语法似乎也有效:
catch let error as AppErrors where [.NotFound, .AlreadyUsed].contains(error)
为了完整起见,我还将添加此选项,它允许我们捕获两种不同类型的错误,但它不允许我们指定这些类型中的哪种情况:
catch let error where error is AppErrors || error is NSError
最后,基于我们捕获的任何符合ErrorType
协议的事实,我们可以清理第二个&第三个示例我提供了一个ErrorType
扩展名,并将where
中的catch
子句与extension ErrorType {
var isFooError: Bool {
guard let err = self as? AppErrors else { return false }
return err == .NotFound || err == .AlreadyUsed
}
}
一起使用:
catch let error where error.isFooError
就这样抓住它:
{{1}}
答案 1 :(得分:1)
您可以创建包含AppErrors
数组的案例:
indirect enum AppErrors: Error {
case NotFound
case AlreadyUsed
case errors([AppErrors])
}
然后,对于catch语句:
catch AppErrors.errors(let errors) where errors == [.NotFound, .AlreadyUsed]
请注意,与errors
比较时,Array
为==
且顺序。另一种方法是使用case errors(Set<AppErrors>)
,但这需要AppErrors
符合Hashable
协议。
更新:想想看,最好使用OptionSet
类型:
public struct InvalidInput: OptionSet, Error {
public var rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
public static let noAccount = InvalidInput(rawValue: 1 << 0)
public static let noKey = InvalidInput(rawValue: 1 << 1)
public static let invalidKey = InvalidInput(rawValue: 1 << 2)
}
func validateInput() throws -> Void {
var invalid: InvalidInput = []
invalid.insert(.noKey)
invalid.insert(.noAccount)
if !invalid.isEmpty {
throw invalid
}
}
do {
try validateInput()
} catch [InvalidInput.noAccount, InvalidInput.noKey] as InvalidInput {
print("Account and key are both required.")
}
链接:http://www.chrisamanse.xyz/2016/12/03/catching-multiple-errors-in-swift