So I tried error handling thing in swift 2. But one thing that I am not sure about is how to get it work for asynchronous callback functions. Suppose I am loading a resource from backend. I defined my error type like the following:
enum NetworkError: ErrorType {
case NoConnection
case InvalidJSON
case NoSuccessCode(code: Int)
}
I am planning to throw one of these cases when something wrong. Here is the function that makes network call:
func loadRequest<T: Decodable>(request: NSURLRequest, callback:T -> Void) throws {
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { data, response, error in
// Other code that parses json and at somewhere it throws
throw NetworkError.NoConnection
}
}
But here compiler gives error:
Cannot invoke
dataTaskWithRequest
with an argument list of type(NSURLRequest, (_,_,_) throws) -> Void)
From here it is obvious that same closure type is considered as a different type when it is declared with throws
.
So how is this do-try-catch thing works in these situations?
An error cannot be thrown asynchronously because the the function will already have returned when the error occurs, you have to handle the error within the closure by calling back to some function with an ErrorType
parameter to decide what you want to do with it. Example:
import Foundation
enum NetworkError: ErrorType {
case NoConnection
case InvalidJSON
case NoSuccessCode(code: Int)
}
func getTask() -> NSURLSessionDataTask? {
let session = NSURLSession.sharedSession()
let urlRequest = NSURLRequest(URL: NSURL(string: "www.google.com")!)
return session.dataTaskWithRequest(urlRequest) { data, response, error in
if let error = error {
asyncError(error)
} else {
// Do your stuff while calling asyncError when an error occurs
}
}
}
func asyncError(error: ErrorType) {
switch error {
case NetworkError.NoConnection:
// Do something
break
default:
break
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With