try? propagates rather than returning nil
error-handling, ios, option-type, swift
Solution
`try?` evaluates the expression and returns `nil` if a Swift error is thrown during the evaluation. In your situation, the Foundation library throws an Objective-C `NSException`, as can be seen if you set an exception breakpoint:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00007fffbe5cb45d libobjc.A.dylib`objc_exception_throw
frame #1: 0x00007fffa9855c3d CoreFoundation`+[NSException raise:format:] + 205
frame #2: 0x00007fffab3a001a Foundation`+[NSJSONSerialization JSONObjectWithStream:options:error:] + 178
Objective-C exceptions cannot be catched in Swift (unless you use an Objective-C wrapper, see for example Catching NSException in Swift).
Problem
My understanding of `try?` was that when the expression following `try?` is evaluated, `nil` will be returned if there is an exception, otherwise the return value of the function will be returned. When I run the following code: ``` guard let istream = InputStream(url: url), let ambiguousObj = try? JSONSerialization.jsonObject(with: istream, options: []), let jsonObj = ambiguousObj as? [[String: Any]] else { throw ExportError.recoveredParseFailed } ``` I get an error pertaining to the second line above: ``` *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization JSONObjectWithStream:options:error:]: stream is not open for reading' ``` I understand how to fix the error. (I needed to call `istream.open()`) But, could someone help me understand why `try?` didn't catch the exception in this case?