Update: Matching NSErrors

Good news, everyone!

While my original post on this topic might be of some small interest in a general “strategies for using expression patterns” kind of way, Swift provides a much better solution for the specific problem of matching NSErrors.

Joe Groff tweets:

NSErrors are bridged to error structs in Swift.

What does that mean in practice? You can find all the gory details in SE-0112, but the long and the short of it is, depending on the domain of a given NSError, Swift automatically bridges it to a struct describing that domain. In the case of NSURLErrorDomain, for example, Swift will bridge to a URLError:

let error = NSError(domain: NSURLErrorDomain,
                code: NSURLErrorTimedOut)
error is URLError //> true

This alone lets us deal with NSErrors in a much more declarative way without thinking about domains (and that’s not to mention all the goodies it gives us that we used to have to dig through userInfo for — like failingURL!)

But there’s more:

Looks like Foundation provides the ~=(T.Code, T) matcher for you.

So to match a timeout in Swift without writing any code, it’s actually as simple as:

catch URLError.timedOut {
  print("timed out!")

Wow! As Doug Gregor writes,

You shouldn’t need to match on NSError nowadays, unless someone is vending an error code not marked with NS_ERROR_ENUM.

I wish I had learned about this a lot earlier. Spread the word! Please and thank you.