swift2 - Swift do-try-catch syntax -
i give try understand new error handling thing in swift 2. here did: first declared error enum:
enum sandwicherror: errortype { case notme case doityourself }
and declared method throws error (not exception folks. error.). here method:
func makemesandwich(names: [string: string]) throws -> string { guard let sandwich = names["sandwich"] else { throw sandwicherror.notme } return sandwich }
the problem calling side. here code calls method:
let kitchen = ["sandwich": "ready", "breakfeast": "not ready"] { let sandwich = try makemesandwich(kitchen) print("i eat \(sandwich)") } catch sandwicherror.notme { print("not me error") } catch sandwicherror.doityourself { print("do error") }
after do
line compiler says errors thrown here not handled because enclosing catch not exhaustive
. in opinion exhaustive because there 2 case in sandwicherror
enum.
for regular switch statements swift can understands exhaustive when every case handled.
there 2 important points swift 2 error handling model: exhaustiveness , resiliency. together, boil down do
/catch
statement needing catch every possible error, not ones know can throw.
notice don't declare types of errors function can throw, whether throws @ all. it's zero-one-infinity sort of problem: defining function others (including future self) use, don't want have make every client of function adapt every change in implementation of function, including errors can throw. want code calls function resilient such change.
because function can't kind of errors throws (or might throw in future), catch
blocks catch errors don't know types of errors might throw. so, in addition handling error types know about, need handle ones don't universal catch
statement -- way if function changes set of errors throws in future, callers still catch errors.
do { let sandwich = try makemesandwich(kitchen) print("i eat \(sandwich)") } catch sandwicherror.notme { print("not me error") } catch sandwicherror.doityourself { print("do error") } catch let error { print(error.localizeddescription) }
but let's not stop there. think resilience idea more. way you've designed sandwich, have describe errors in every place use them. means whenever change set of error cases, have change every place uses them... not fun.
the idea behind defining own error types let centralize things that. define description
method errors:
extension sandwicherror: customstringconvertible { var description: string { switch self { case notme: return "not me error" case doityourself: return "try sudo" } } }
and error handling code can ask error type describe -- every place handle errors can use same code, , handle possible future error cases, too.
do { let sandwich = try makemesandwich(kitchen) print("i eat \(sandwich)") } catch let error sandwicherror { print(error.description) } catch { print("i dunno") }
this paves way error types (or extensions on them) support other ways of reporting errors -- example, have extension on error type knows how present uialertcontroller
reporting error ios user.
Comments
Post a Comment