Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get userInfo from NSError in catch clause

If I have a throwing method, like so:

func doSomethingWithString(string:String) throws {
  guard string.characters.count > 0 else {
    throw NSError(domain: "CustomErrorDomain", code: 42, userInfo: ["foo" : "bar"])
  }
  // Do something with string...
}

Then I try to call it and read the userInfo:

do {
  try doSomethingWithString("")
} catch let error as NSError {
  print(error.domain)
  print(error.code)
  print(error.userInfo)
}

... it comes back as an empty dictionary, (but the domain and code are correctly populated):

CustomErrorDomain
42
[:]

But if I add in this extra step:

do {
  try doSomethingWithString("")
} catch let e {
  let error = e as NSError
  print(error.domain)
  print(error.code)
  print(error.userInfo)
}

...it works:

CustomErrorDomain
42
[foo: bar]

Does anybody know why this might be?

FYI - I am on Xcode 7 beta 2 (7A121l)

like image 316
ganzogo Avatar asked Jul 03 '15 08:07

ganzogo


1 Answers

It's a bug, fixed in Xcode 7 Beta 4. Here's extracts from the Release Notes (PDF, page 15):

Resolved Issues in Xcode 7 beta 4 — Swift 2.0 and Objective-C

When throwing a reference to an NSError instance in Swift, the Swift runtime no longer loses the userInfo of the original NSError if it is caught as an NSError. The Swift runtime now preserves the identity of the original NSError. For example, this assertion now holds:

 let e = NSError(...)
 do {
   throw e
 } catch let e2 as NSError {
   assert(e === e2)
 }
like image 193
Code Different Avatar answered Oct 08 '22 07:10

Code Different