{"id":11515,"date":"2015-06-19T11:12:08","date_gmt":"2015-06-19T15:12:08","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=11515"},"modified":"2019-03-13T15:21:22","modified_gmt":"2019-03-13T19:21:22","slug":"swift-2-error-handling-continued","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2015\/06\/19\/swift-2-error-handling-continued\/","title":{"rendered":"Swift 2 Error Handling, Continued"},"content":{"rendered":"<p><a href=\"https:\/\/medium.com\/swift-programming\/keep-your-swift-exceptions-clean-easy-to-update-and-future-proof-20b997d0b46c\">Mikael Konradsson<\/a>:<\/p>\n<blockquote cite=\"https:\/\/medium.com\/swift-programming\/keep-your-swift-exceptions-clean-easy-to-update-and-future-proof-20b997d0b46c\"><p>Finally a [decent] exception model in a modern language, a model where it&rsquo;s absolutely obvious when to use <code>do\/try\/catch<\/code>. If you miss it, the compiler (precompiler\/static analyzer) will tell you. There is no, or very little overhead in using Exceptions in Swift, unlike Java and C# where the runtime must create the exception and unwind the stack and then throw.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/www.libertypages.com\/clarktech\/?p=690\">Clark Goble<\/a>:<\/p>\n<blockquote cite=\"http:\/\/www.libertypages.com\/clarktech\/?p=690\"><p>My own view is that people are perhaps taking things too seriously. Swift is a very pragmatic language and it&rsquo;s developing with a set of practical concerns. Mainly the connection to ObjC based Cocoa libraries. Maybe that&rsquo;s undermining what the language <em>could<\/em> be. But especially for the next years, the primary purpose of Swift will be to code against Cocoa. For all the problems and limits of Swift exceptions, they do seem a big step up from difficult to read nested if statements. Maybe this decision will limit Swift in the future. But in the present it&rsquo;ll make most people&rsquo;s life easier.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/www.hackingwithswift.com\/new-syntax-swift-2-error-handling-try-catch\">Paul Hudson<\/a>:<\/p>\n<blockquote cite=\"http:\/\/www.hackingwithswift.com\/new-syntax-swift-2-error-handling-try-catch\"><p>This does have one downside: if you add any future values to the enum, which we&rsquo;re about to do, it will just drop into the default <code>catch<\/code> block &#8211;&nbsp;you won&rsquo;t be asked to provide any code for it as would happen with a <code>switch\/case<\/code> block.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/owensd.io\/2015\/06\/16\/do-catch.html\">David Owens II<\/a>:<\/p>\n<blockquote cite=\"http:\/\/owensd.io\/2015\/06\/16\/do-catch.html\"><p>The latest thing I&rsquo;m running up against in the cumbersomeness of the <code>do-catch<\/code> pattern for handling errors. Not only that, I think it promotes the bad exception handling that Java had with people simply writing a single <code>catch (Exception e)<\/code> handler.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/www.hackingwithswift.com\/new-syntax-swift-2-defer\">Paul Hudson<\/a>:<\/p>\n<blockquote cite=\"http:\/\/www.hackingwithswift.com\/new-syntax-swift-2-defer\"><p>Swift 2 introduces the <code>defer<\/code> keyword, which effectively means &ldquo;here&rsquo;s some what I want you to do later, no matter what.&rdquo; That work can be whatever you want: a single method call closing a file, or 50 lines of code doing some other important clean up work. The important thing is that Swift ensures that it will be run before the current scope is ended.<\/p>\n<p>[&#8230;]<\/p>\n<p>One of the most powerful features of <code>defer<\/code> is that you can stack up multiple deferred pieces of work, and Swift will ensure they all get executed. What&rsquo;s more, it executes them in reverse order, meaning that the most recently deferred thing gets run first &#8211; effectively unwinding a stack.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/gist.github.com\/nicklockwood\/21495c2015fd2dda56cf\">Nick Lockwood<\/a> on <a href=\"http:\/\/mjtsai.com\/blog\/2015\/06\/12\/swift-2-error-handling-in-practice\/\">Brad Larson&rsquo;s post<\/a>:<\/p>\n<blockquote cite=\"https:\/\/gist.github.com\/nicklockwood\/21495c2015fd2dda56cf\"><p>If you look at the examples in that article, the reason why the result enum doesn&rsquo;t work well for him is that the methods being called are primarily synchronous, and without return values. They aren&rsquo;t pure functions. [&#8230;] But does that mean result types are bad? No, they&rsquo;re pretty awesome for functions that actually return a result that we want to pass to the next function (possibly an unspecified amount of time later). They just aren&rsquo;t great for handling errors produced by procedures that don&rsquo;t return anything, and execute sequentially on the same thread, because they must be checked after every call, and that quickly becomes tedious.<\/p>\n<p>[&#8230;]<\/p>\n<p>But <code>try<\/code> only works in this one situation, with sequential imperative statements. If Brad Larson was working on something like a network library instead of a robot controller, result types would work much better for error propagation than Swift 2&rsquo;s exceptions, because exception-style errors don&rsquo;t really work for asynchronous, callback-based APIs.<\/p>\n<p>[&#8230;]<\/p>\n<p>It&rsquo;s gross that we have two totally different ways to handle errors based on whether the following line needs to use the output from the previous line, and whether it&rsquo;s called immediately, or after an async calculation. And Swift&rsquo;s try\/catch semantics do nothing to help reduce the error handling boilerplate needed inside callbacks.<\/p>\n<\/blockquote>\n\n<p><a href=\"http:\/\/robnapier.net\/throw-what-dont-throw\">Rob Napier<\/a>:<\/p>\n<blockquote cite=\"http:\/\/robnapier.net\/throw-what-dont-throw\"><p>And &ldquo;throws&rdquo; is probably best thought of as somewhat opaque sugar around an Either type.<\/p>\n<p>[&#8230;]<\/p>\n<p>In fact, <code>(Int) -&gt; String<\/code> is a <em>subtype<\/em> of <code>(Int) throws -&gt; String<\/code>, which is\npretty awesome and a little subtle, but we&rsquo;ll get to that in another post.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/robnapier.net\/re-throws\">Rob Napier<\/a>:<\/p>\n<blockquote cite=\"http:\/\/robnapier.net\/re-throws\"><p>So that tells us that a non-throwing closure can be used anywhere a throwing closure is requested, just like a Cat can be used anywhere an Animal is requested. No conversions necessary. It&rsquo;s just types.<\/p>\n<p>[&#8230;]<\/p>\n<p>Luckily, Swift is much smarter than that. It&rsquo;s nice that you can overload based\non throwing, but in many cases we have a better tool. We can mark the method\n<code>rethrows<\/code> rather than <code>throws<\/code>.<\/p>\n<pre>func map&lt;T&gt;(@noescape transform: (Generator.Element) throws -&gt; T) rethrows -&gt; [T]<\/pre>\n<p>So what promise does <code>rethrows<\/code> make? It promises that the only way it will\nthrow is if a closure it is passed throws. So if it&rsquo;s passed a closure that\ncan&rsquo;t throw, the compiler knows that the function can&rsquo;t throw either.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/sketchytech.blogspot.com\/2015\/06\/closures-that-throw-rethrows-in-swift-20.html\">Anthony Levings<\/a>:<\/p>\n<blockquote cite=\"http:\/\/sketchytech.blogspot.com\/2015\/06\/closures-that-throw-rethrows-in-swift-20.html\"><p>Internally the rethrowing function uses the <code>try<\/code> keyword as usual, but does not require the <code>do<\/code> and <code>catch<\/code> elements. It is only when the function is called that the do-try-catch syntax is employed.<\/p><\/blockquote>\n\n<p><a href=\"http:\/\/ericasadun.com\/2015\/06\/18\/swift-asynchronous-error-handling\/\">Erica Sadun<\/a>:<\/p>\n<blockquote cite=\"http:\/\/ericasadun.com\/2015\/06\/18\/swift-asynchronous-error-handling\/\"><p>If you&rsquo;re working with asynchronous closures, you&rsquo;ll need to supply ones that do not use throwing signatures. Convert your closures to non-throwing versions by providing exhaustive catch clauses.<\/p><\/blockquote>\n\n<p>Update (2015-06-22): <a href=\"http:\/\/www.figure.ink\/blog\/2015\/6\/20\/swift-exceptions-are-swifty-part-1\">Joshua Emmons<\/a>:<\/p>\n<blockquote cite=\"http:\/\/www.figure.ink\/blog\/2015\/6\/20\/swift-exceptions-are-swifty-part-1\"><p>It&rsquo;s telling that exceptions have arrived in the language alongside multi-payload enums. This makes it trivial to create  <code>Either<\/code> types without the awkward, inefficient boxing of values previously required. And it would seem exceptions take advantage of this. <code>throws<\/code> is just syntactic sugar.<\/p><\/blockquote>\n\n<p>Update (2015-06-25): <a href=\"https:\/\/www.bignerdranch.com\/blog\/error-handling-in-swift-2\/\">Juan Pablo Claude<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.bignerdranch.com\/blog\/error-handling-in-swift-2\/\"><p>Swift 2.0 does a great job of coalescing the history of error handling in Cocoa and Cocoa Touch into a modern idiom that will feel familiar to many programmers. Unifying behavior leaves the Swift language and the frameworks it inherits in a good position to evolve.<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Mikael Konradsson: Finally a [decent] exception model in a modern language, a model where it&rsquo;s absolutely obvious when to use do\/try\/catch. If you miss it, the compiler (precompiler\/static analyzer) will tell you. There is no, or very little overhead in using Exceptions in Swift, unlike Java and C# where the runtime must create the exception [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2019-03-13T19:21:25Z","apple_news_api_id":"57986a52-3a37-4672-bb0f-4d3ee9f79964","apple_news_api_modified_at":"2019-03-13T19:21:27Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/AV5hqUjo3RnK7D00-6feZZA","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[69,79,31,46,30,857,71,901],"class_list":["post-11515","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-cocoa","tag-exceptions","tag-ios","tag-languagedesign","tag-mac","tag-nserror","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/11515","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=11515"}],"version-history":[{"count":5,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/11515\/revisions"}],"predecessor-version":[{"id":24592,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/11515\/revisions\/24592"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=11515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=11515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=11515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}