I have searched around for a bit and couldn't find anything - not even a question on this site - so now I wonder whether Swift 2 supports multi-catch blocks like Java does.
Java-Example:
try {
someMethod(); // throws ExceptionOne, ExceptionTwo
} catch(ExceptionOne | ExceptionTwo e) {
handleMyException();
} catch(Exception e2) {
handleOtherExceptions();
}
In Swift, I wasn't able to implement a similar solution. This question explains a nice way to handle different errors of one ErrorType
enum, but my requirements seem to be different as my error is initialized with a message coming from an HTTP-response. This is my enum:
enum HTTPError: ErrorType {
case BAD_REQUEST(message: String)
case UNAUTHORIZED(message: String)
case NOT_FOUND
case INTERNAL_SERVER_ERROR(message: String)
case NOT_IMPLEMENTED(message: String)
static func getErrorForStatusCode(statusCode: Int, message: String? = nil) -> HTTPError {
switch statusCode {
case 400:
return HTTPError.BAD_REQUEST(message: message!)
case 401:
return HTTPError.UNAUTHORIZED(message: message!)
case 404:
return HTTPError.NOT_FOUND
case 500:
return HTTPError.INTERNAL_SERVER_ERROR(message: message!)
case 501:
return HTTPError.NOT_IMPLEMENTED(message: message!)
default:
return HTTPError.INTERNAL_SERVER_ERROR(message: message!)
}
}
}
When I want to throw an error of that enum, I use such code:
func someMethod() throws {
...
HTTPError.getErrorForStatusCode(400, message: "Field X missing") // Actual values coming from HTTP-response
...
}
Now, in the calling method, I have to catch every error of the enum separately, although I want them all to do the same (except for the NOT_FOUND
, but that doesn't matter here):
try {
someMethod() // throws
} catch HTTPError.BAD_REQUEST(let message) {
// display 'message' to user
} catch HTTPError.UNAUTHORIZED(let message) {
// display 'message' to user
} catch HTTPError.INTERNAL_SERVER_ERROR(let message) {
// display 'message' to user
}
...
Does Swift 2 really not contain multi-catch? Or is there another solution that would help me solve my problem?
EDIT: It seems my desired behavior isn't quite clear: I want to handle the errors of type HTTPError (except HTTPError.NOT_FOUND) in the same way, that's why I'm asking for multi-catch.
I will still implement a general catch-block to cover all errors I'm not aware about (eg timeout, nil-access, ...), but those errors that come with a backend-message should be treated specially.
Thanks, chuky
Swift 2 does support multi-catch
From the documentation
You write a pattern after catch to indicate what errors that clause can handle. If a catch clause doesn't have a pattern, the clause matches any error and binds the error to a local constant named
error
.
So get that error
constant and use a switch
statement.
do {
try someMethod() // throws
} catch let error as HTTPError {
switch error {
case .NOT_FOUND:
print("not found")
case let message: // handle all errors with a message
print(message)
}
}
or with catch
pattern
do {
try someMethod() // throws
} catch HTTPError.NOT_FOUND {
print("not found")
} catch let message {
print(message)
}
which is also exhaustive because all other cases have a message.
Apart from that you – the developer – are supposed to know exactly the number of cases in the enum so you can handle them reliably.
Edit:
Another solution is to add a associatedValue
property inside the enum
var associatedValue : String {
switch self {
case BAD_REQUEST(let value) : return value
case UNAUTHORIZED(let value) : return value
case INTERNAL_SERVER_ERROR(let value) : return value
case NOT_IMPLEMENTED(let value) : return value
default: return ""
}
}
and use this switch statement
do {
try someMethod() // throws
} catch HTTPError.NOT_FOUND {
print("not found")
} catch let error as HTTPError {
print(error.associatedValue)
}
enum Error: ErrorType {
case E1
case E2
case E3
}
func foo(e: Error) throws {
throw e
}
do {
try foo(Error.E2)
} catch Error.E1 {
print(Error.E1) // only Error.E1
} catch {
print("error: ", error) // all other errors
}
/*
error: E2
*/
Swift 5.3 现在支持多模式捕获 查看提案详细信息: https : //github.com/apple/swift-evolution/blob/master/proposals/0276-multi-pattern-catch-clauses.md
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.