Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous error handling in swift 2

Tags:

swift

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?

like image 800
mustafa Avatar asked Jun 12 '15 22:06

mustafa


1 Answers

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
    }
}
like image 155
Kametrixom Avatar answered Nov 17 '22 02:11

Kametrixom