potentially throw an exception } @catch (NSException *exception) { // Handle an exception thrown in the @try block } @finally { // Code that gets executed // whether or not an exception is thrown } … but rarely used in Objective-C
E> -> Void)) ... doAsync(arg) { result in switch result { case .Success(let value): // do success handling case .Failure(let error): // do error handling } }
or throws error (ErrorType) • Must declare throws / rethrows • Supertype of non-throwing function • Works swiftly with existing Objective-C Cocoa APIs • Can set breakpoint (e.g. br s -E swift -O MyError) • Similar to Java’s Checked Exception (not NSException)
of program control & should be recoverable • Forces caller to use do-catch conditional blocks • No unwinding callstack penalties for unhandled errors • Unchecked Exception • Programmer’s mistake & should NOT be recoverable
is required for **every ** call of throwing function • or, try! (forced-try) to omit do-catch blocks • catch clause can be used like switch statement • Use defer in replace of “finally”
result3 { case .Success(let value3): // do success handling case .Failure(let error): // do error handling } Functional All Error types must be same...
{…}) switch result3 { case .Success(let value3): // do success handling case .Failure(let error): // do error handling } Error conversion is sometimes required...
doSync1(arg) let value2 = try doSync2(value1) let value3 = try doSync3(value2) // do success handling } catch { // do error handling } Imperative Can catch any ErrorTypes
throw MyError.XXX case 1: throw YourError.YYY default: throw HisError.ZZZ } } Too loose ErrorType No ErrorType info Can throw many different ErrorTypes
No `()`, please… • Ideally, it’s better if we can try Result<T, E> enum rather than try throwing function • Too verbose for sync task & can’t throw immediately • Use lazy throwing for async only? (but it will lack consistency…)
Enum • Same weight for both success value and error • No compiler support (breakpoint, do-catch) • Too easy to ignore errors • var value: T? … Result → Optional conversion • map() / flatMap() … using success value without checking error
E1> = ... let value = try result let value: T1 switch result { case .Success(let v1): value = v1 case .Failure(let e1): return .Failure(E2.convertFrom(e1)) } 㱻
E1> = ... let value = try result let value: T1 switch result { case .Success(let v1): value = v1 case .Failure(let e1): return .Failure(E2.convertFrom(e1)) } Early-exit with auto-mapping Error! 㱻