In swift how do I throw an error within a completion handler like this:
    let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
        (data, response, error) in
        do {
            //something
            completion(result)
        } catch let jsonError {
            throw CustomError.myerror //THIS DOESN'T WORK
        }
    })
    task.resume()
as the error is
Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(Data?, URLResponse?, Error?) -> Void'
Short story: You can't throw in a dataTask completion closure
You could return two values in the completion handler
...completion: @escaping (ResultType?, Error?)->Void
and return
completion(result, nil)
completion(nil, CustomError.myerror)
or more convenient use an enum with associated type
enum Result {
    case success(ResultType), failure(Error)
}
...completion: @escaping (Result)->Void
and return
completion(.success(result))
completion(.failure(CustomError.myerror))
You can process the result
foo() { result in
    switch result {
    case .success(let resultType): // do something with the result
    case .failure(let error): // Handle the error
    }
}
Update:
In Swift 5 using the new built-in Result type it's even more comfortable because Result can capture the result of the throwing expression
...completion: @escaping (Result<MyType,Error>)->Void
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
    (data, response, error) in
    completion(Result { try something()})
})
task.resume()
                        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