简体   繁体   中英

try-catch inside closure -> Invalid conversion from throwing to non-throwing function type

I have marked my function with throws, why does swift force me to use a do-try-catch block?

I want to handle any kind of error thrown where I call this function below.

static func getPosts() throws {

    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")
    let request = URLRequest(url: url!)

    let session = URLSession.shared
    session.dataTask(with: request) { (data, response, error) in

        let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves) as! [String: Any]  

    }.resume()        
}

Below is screen-shot of error I am getting.

Your throws is saying that your getPosts() function itself will throw. However, it finished before the closure is called, which means that even if the json parsing throws exception, you have passed the time that the exception can be caught and handled.

Errors within a closure has to be handled in the closure. You are looking for something like

static func getPosts(completion: @escaping (_ error: String) -> Void) {

    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")
    let request = URLRequest(url: url!)

    let session = URLSession.shared
    session.dataTask(with: request) { (data, response, error) in
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableLeaves) as! [String: Any]
            completion("ok")
        }catch let error {
            print(error)
            completion("error")
        }

    }.resume()        
}

It's impossible to catch an error from within a closure.

A suitable solution is an enum and a completion handler

enum PostResult {
    case success([String:Any]), failure(Error)
}

func getPosts(completion:@escaping (PostResult)->() ) {

    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")!
    // no URLRequest needed !
    let session = URLSession.shared
    session.dataTask(with: url) { (data, response, error) in
        if let error = error { 
            completion(.failure(error)) 
            return
        }
        do {
            let json = try JSONSerialization.jsonObject(with: data!) as! [String: Any]
            completion(.success(json))
        } catch {
            completion(.failure(error))
        }

    }.resume()
}

And use it

getPosts { result in
    switch result {
    case .success(let json): print(json)
         // process json 
    case .failure(let error): print(error)
         // handle error
    }
}

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.

Related Question Alamofire 4 Invalid conversion from throwing function of type '(_) throws -> ()' to non-throwing function type '(DataResponse<Any>) -> Void' Invalid conversion from throwing function of type '(Data) throws -> ()' to non-throwing function type '(Data) -> ()' Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(URLResponse?, Data?, Error?) -> Void Invalid conversion from throwing function type (_,_,_) throws to non-throwing function type (Data?, Response?, URLResponse?) Void Invalid conversion from throwing function of type '(_, _) throws -> ()' to non-throwing function type '(JSON?, Error?) -> Void' Invalid conversion from throwing function of type '(_) throws -> ()' to non-throwing function type '(Response) -> Void' Error: Invalid conversion from throwing function of type '(_) throws -> ()' to non-throwing function type '(DataSnapshot) -> Void' Invalid conversion from throwing function of type '(_) throws -> Void' to non-throwing function type '([UNNotificationRequest]) -> Void Errors migrating to Swift 2: Invalid conversion from throwing function of type to non-throwing function type and use of undeclared type Invalid conversion from throwing function of type (_,_,_) throws -> Void to non-throwing function type (NSData?, NSURLResponse?, NSError?) -> Void
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM