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

Swift 2 - Error Handling

Swift 2 - Error Handling

An overview about Swift 2's new built-in error handling, an exploration how it works and how it can be tested, and a quick comparison with the approach of a Result type.

Marius Rackwitz

August 17, 2015
Tweet

More Decks by Marius Rackwitz

Other Decks in Programming

Transcript

  1. public struct Account { public enum Error : ErrorType {

    case TransactionExceedsFunds case NonPositiveTransactionNotAllowed(amount: Int) } var fund: Int public mutating func withdraw(amount: Int) throws { guard amount < fund else { throw Error.TransactionExceedsFunds } guard amount > 0 else { throw Error.NonPositiveTransactionNotAllowed(amount: amount) } fund -= amount } }
  2. enum Error : ErrorType { case NoArgumentGiven case ArgumentIsNotAnInteger }

    var arguments = Process.arguments // Remove the executable name. assert(arguments.count >= 1) arguments.removeAtIndex(0) guard let firstArg = arguments.first else { throw Error.NoArgumentGiven } guard let amount = Int(firstArg) else { throw Error.ArgumentIsNotAnInteger }
  3. let dict = NSMutableDictionary(contentsOfFile: "account.plist") ?? NSMutableDictionary() let fund =

    dict["fund"] as? Int ?? 100 var account = Account(fund: fund) do { try account.withdraw(amount) dict["fund"] = account.fund dict.writeToFile("account.plist", atomically: true) } catch Account.Error.NonPositiveTransactionNotAllowed(let amount) { print("Amount (\(amount)) must be positive.") } catch Account.Error.TransactionExceedsFunds { print("Amount exceeds account balance (\(account.fund)).") } catch { print("An unexpected error <\(error)> occured.") }
  4. A throwing method can’t override a nonthrowing method, and a

    throwing method can’t satisfy a protocol requirement for a nonthrowing method. …
  5. … That said, a nonthrowing method can override a throwing

    method, and a nonthrowing method can satisfy a protocol requirement for a throwing.
  6. Model protocol ThrowingFunction { typealias ParameterType typealias ReturnType func call(parameter:

    ParameterType) throws -> ReturnType } protocol NonThrowingFunction : ThrowingFunction { func call(parameter: ParameterType) -> ReturnType }
  7. as throwing let str: String var x = 0 do

    { try parse(str) { (char) in if char == "+" { x += 1 } else { throw Error.UnexpectedChar } } } catch error { print("Error occured while parsing: \(error)") }
  8. // from SwiftExP public enum Error : ErrorType { case

    UnexpectedEOS case IllegalNumberFormat(numberString: String) case IllegalEscapeSequence(escapeSequence: String) case NonTerminatedList case NonTerminatedQuotedString case IllegalHexCharacter(char: Character) }
  9. struct Error : ErrorType { // Not necessary since Xcode

    7b5, // but let you avoid to write underscores. var code: Int var domain: String var _code: Int { return code } var _domain: String { return domain } }
  10. Swift's Error Throwing under the hood · Breaks the control

    flow · Syntax sugar around NSError pointers · Isn't as expensive as Objective-C exceptions
  11. class Object { } enum Error : ErrorType { case

    HelloWorld } func foo(x: Int) throws -> Object { let obj = Object() if x == 0 { throw Error.HelloWorld } return obj } try foo(0)
  12. enum BombError: ErrorType { case WrongWire case TimeElapsed } let

    ! = BombError.TimeElapsed let " = 11 let # = 12 func $(time: Int) throws { if time >= # { throw ! } } class ExampleTests : XCTestCase { func testDoNotDisarm() { AssertNoThrow(try $(")) AssertThrows(!, try $(#)) } }
  13. Async 1 : 1 The try-catch model actively breaks the

    current control flow. But Result values can be passed around arbitrarily.
  14. Protocol-oriented Programming 2 : 2 A non-throwing method can fulfill

    a throwing protocol requirement. A Result type can be generically parameterized with a stub type NoError.
  15. Takeaways · Avoid try!, but prefer it instead of empty

    catch blocks. · Catch Foundation errors by pattern matches with NSCocoaError constructors · File a Radar if the error is not exposed / there is no obvious adequate