Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Me and Swift and error

Me and Swift and error

Presented at “Swift 2 (& LLDB) Symposium”

58b40ae3b0db6cf0202a3802e9dd70fe?s=128

cockscomb

July 03, 2015
Tweet

Transcript

  1. ૪ ࠴  ࡻ ࡨ ࡥ ࢗ ࢊ ࠴ 

    ࡪ ࢫ ߭
  2. cockscomb

  3. None
  4. ࡻ ࡨ ࡥ ࢗ ࢊ

  5. Swift 2

  6. ࡪ ࢫ ߭

  7. Error Handling

  8. • Error Handling Basics • guard, defer • Closure •

    Asynchronous callback • Exhaustive
  9. Error Handling Basics

  10. enum MyError: Int { static let domain = "MyErrorDomain" case

    DangerousError = -999 } func awesome(error: NSErrorPointer) -> String? { error.memory = NSError(domain: MyError.domain, code: MyError.DangerousError.rawValue, userInfo: nil) return nil } func test() { var error: NSError? let result = awesome(&error) if let r = result { print(r) } if let e = error { print(e) } } test() Swift 1.x
  11. enum MyError: ErrorType { case DangerousError } func awesome() throws

    -> String { if fail { throw MyError.DangerousError } return "awesome" } func test() { do { let result = try awesome() print(result) } catch { print("Error") } } test() Using ErrorType
  12. enum MyError: ErrorType { case DangerousError(String) } func awesome() throws

    -> String { if fail { throw MyError.DangerousError("Too dangerous") } return "awesome" } func test() { do { let result = try awesome() print(result) } catch MyError.DangerousError(let message) { print(message) } catch { print("Error") } } test() Error information
  13. enum MyError: ErrorType { case DangerousError } func awesome() throws

    -> String { if fail { throw MyError.DangerousError } return "awesome" } func test() throws { let result = try awesome() print(result) } do { try test() } catch { print("Error") } Propagate error
  14. enum MyError: ErrorType { case DangerousError } func awesome() throws

    -> String { if fail { throw MyError.DangerousError } return "awesome" } func test() { let result = try! awesome() print(result) } test() Forced-try
  15. Error Handling Basics • Before Swift 2, NSErrorPointer • ErrorType

    • throw, try, catch • Propagation
  16. guard, defer

  17. struct Dog { enum Error: ErrorType { case Sleeping }

    enum State { case Sitting case Sleeping case Walking } var state: State = .Sitting mutating func walk() throws { guard state != .Sleeping else { throw Error.Sleeping } state = .Walking } } guard
  18. struct Human { enum State { case Standing case Walking

    } var state: State = .Standing mutating func walk(inout dog: Dog) throws { defer { dog.praise() } try dog.walk() state = .Walking } } defer
  19. Closure

  20. enum MyError: ErrorType { case DangerousError } func execute(closure: ()

    throws -> Void) throws { try closure() } do { try execute({ throw MyError.DangerousError }) } catch { print("Error") } Closures can throw
  21. enum MyError: ErrorType { case DangerousError } func execute(closure: ()

    throws -> Void) throws { try closure() } do { try execute({ print("No error") }) } catch { print("Error") } Assumed no error but catch
  22. enum MyError: ErrorType { case DangerousError } func execute(closure: ()

    throws -> Void) rethrows { try closure() } execute({ print("No error") }) Assumed no error
  23. Closure • try closure • rethrows

  24. Asynchronous callback

  25. enum MyError: ErrorType { case DangerousError } func doAsync(callback: (result:

    String?, error: ErrorType?) -> Void) { dispatch_async(dispatch_get_main_queue()) { callback(result: nil, error: MyError.DangerousError) } } doAsync { (result, error) in if let result = result { print(result) } else if let error = error { print("Error") } } Asynchronous callback
  26. enum MyError: ErrorType { case DangerousError } func doAsync(callback: (()

    throws -> String) -> Void) { dispatch_async(dispatch_get_main_queue()) { callback({ throw MyError.DangerousError }) } } doAsync { (f) in do { let result = try f() } catch { print("Error") } } Asynchronous callback
  27. enum ValueOrError<T> { case Value(T) case Error(ErrorType) init(_ value: T)

    { self = Value(value) } init(_ error: ErrorType) { self = Error(error) } func get() throws -> T { switch self { case .Value(let value): return value case .Error(let error): throw error } } } Value or Error
  28. enum MyError: ErrorType { case DangerousError } func doAsync(callback: (ValueOrError<String>)

    -> Void) { dispatch_async(dispatch_get_main_queue()) { callback(ValueOrError(MyError.DangerousError)) } } doAsync { (v) in do { let result = try v.get() } catch { print("Error") } } Asynchronous callback
  29. Asynchronous callback • Optional, Optional • f: () throws ->

    Result • ValueOrError value
  30. func doAsync(callback : String catches -> Void) { if (success)

    { callback("hooray!") } else { callback(throw MyError.Failed) } } doAsync { result in // handle result } catch { // Catch async thrown error } Suggested in developer forums https://forums.developer.apple.com/thread/4354 Unreal
  31. Exhaustive

  32. –The Swift Programming Language “Like a switch statement, the compiler

    attempts to infer whether catch clauses are exhaustive. If such a determination can be made, the error is considered handled.”
  33. enum MyError: ErrorType { case DangerousError } func doSomething() throws

    { throw MyError.DangerousError } func test() { do { try doSomething() } catch MyError.DangerousError { print("Error") } }
  34. Errors thrown from here are not handled b ! enum

    MyError: ErrorType { case DangerousError } func doSomething() throws { throw MyError.DangerousError } func test() { do { try doSomething() } catch MyError.DangerousError { print("Error") } } Not exhaustive
  35. Errors thrown from here are not handled because the enclosing

    catch is not exhaustive. !
  36. Errors thrown from here are not handled b ! enum

    MyError: ErrorType { case DangerousError } func doSomething() throws { throw MyError.DangerousError } func test() { do { try doSomething() } catch MyError.DangerousError { print("Error") } } Not exhaustive
  37. • Error Handling Basics • guard, defer • Closure •

    Asynchronous callback • Exhaustive
  38. ૪ ࠴  ࡻ ࡨ ࡥ ࢗ ࢊ ࠴ 

    ࡪ ࢫ ߭