Reputation:
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.
Upvotes: 0
Views: 571
Reputation: 285082
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
}
}
Upvotes: 0
Reputation: 25261
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()
}
Upvotes: 0