2

I've started converting one of my projects to Swift 2 and I ran into this issue. To start this block below is perfectly valid try/catch, in fact it was generated by the Xcode migration tool.

do {
       requestData = try NSJSONSerialization.dataWithJSONObject(requestContents, options: [])
} catch var error as NSError {
      requestError = error
      requestData = nil
}

If I use that same code inside a closure, such as a dataTaskWithRequest I get an error. The error is at the task assignment, but its the catch that causes it. The following also works but I'm not capturing the error.

let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, taskError) -> Void in
    if taskError != nil {
        NSLog("Error making request: " + taskError!.localizedDescription)
    } 
    else {
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
            if let parseJSON = json as NSDictionary? {
                // do some parsing here
            }
        } 
        catch {
           NSLog("Error in JSON serialization")
     }
  }
})
task.resume()

but if I try to capture the error with:

} catch let e as NSError {

I get this error:

Invalid conversion from throwing function of type '(_, _, _) throws -> Void' to non-throwing function type '(NSData?, NSURLResponse?, NSError?) -> Void'

I did discover that:

} catch _ {

works but a lot of good that does me.

Am I missing something or should I be filing a bug?

(This is Xcode 7b5)

Unheilig
  • 16,196
  • 193
  • 68
  • 98
rjb101
  • 514
  • 5
  • 14

1 Answers1

3

The completion handler of dataTaskWithRequest is not designed to throw error like JSONObjectWithData of NSJSONSerialization, whose signature is:

class func JSONObjectWithData(data: NSData, options opt: NSJSONReadingOptions) throws -> AnyObject

Doing the following would work (same as what you have tried):

catch _

But that won't give us any detail about the error from the one that throws, namely, from class func JSONObjectWithData.

As a result, we need a way to consume the non-throwable dataTaskWithRequest while preserving the one that throws - JSONObjectWithData.

I have tried the following:

catch let error as NSError
{
     //error specific to JSON serialization
     NSLog("Error in JSON serialization \(error)")
}
catch
{
     //exhaust the error
     NSLog("Some error")
}
Unheilig
  • 16,196
  • 193
  • 68
  • 98
  • 1
    perfect. I wouldn't have thought to do that unless I was throwing custom ErrorType. Thanks !! – rjb101 Aug 21 '15 at 04:34