首页 > 解决方案 > 从 dataTask completionHandler 抛出错误

问题描述

快速我如何在这样的完成处理程序中抛出错误:

    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()

因为错误是

从 '(_, _, _) throws -> ()' 类型的抛出函数到非抛出函数类型 '(Data?, URLResponse?, Error?) -> Void' 的无效转换

标签: swiftnsurlsessiondatatask

解决方案


短篇小说:你不能throwdataTask完成关闭

您可以在完成处理程序中返回两个值

...completion: @escaping (ResultType?, Error?)->Void

并返回

completion(result, nil)
completion(nil, CustomError.myerror)

或更方便地使用具有关联类型的枚举

enum Result {
    case success(ResultType), failure(Error)
}

...completion: @escaping (Result)->Void

并返回

completion(.success(result))
completion(.failure(CustomError.myerror))

您可以处理结果

foo() { result in
    switch result {
    case .success(let resultType): // do something with the result
    case .failure(let error): // Handle the error
    }
}

更新:

在使用新的内置Result类型的 Swift 5 中,它更加舒适,因为Result可以捕获抛出表达式的结果

...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()

推荐阅读