Asynchronous Error Handling
Contents |
where throw async error handling can’t really fit? What’s wrong with throw and async? As a swift async throw reminder, a function which can fail can use throw in the following way: // Define
Asynchronous Error Definition
an error type and a throwing function enum ComputationError: ErrorType { case DivisionByZero } func inverse(x: Float) throws swift error handling async -> Float { guard x != 0 else { throw ComputationError.DivisionByZero } return 1.0/x } // Call it do { let y = try inverse(5.0) } catch { print("Whoops: \(error)") } But what happens when the function is asynchronous and will only return a result later, e.g. with a completion block? func fetchUser(completionPromises In Swift Share Clone via HTTPS Clone with Git or checkout with SVN using the repository's web address. HTTPS Learn more about clone URLs Download ZIP Code Revisions 11 Stars 1 Forks 1 Asynchronous Error Handling in Swift 2.0 Raw async_error_handling.md Asynchronous Error Handling in Swift 2.0 As Swift 1.0 did not include support for http://alisoftware.github.io/swift/async/error/2016/02/06/async-errors/ exceptions, a common error handling pattern was to use a Result enum that either took on a value on success, or an error on failure. In a way, this was superior to using exceptions, since being a instantiable type, Results could be passed around freely, enabling asynchronous code to use the same error handling mechanisim as synchronous code. Using Swift's robust support for custom operators, this https://gist.github.com/CodeOmar/ead32cfdf7a1c27a7b5a also enabled Railway Oriented Programming for more functional oriented programers. Swift 2.0 introduces throwable errors, which are similar to exceptions. However, like exceptions, thrown errors propogate only down the call stack and can only be caught in the same thread that threw them. In order to propogate the errors upwards (such as to callback routines) and across thread boundaries it is necessary to catch the errors and pass them along in some sort of instantiable type, and however this is done, it is preferable to be able to later handle those errors the same way as all other thrown errors. One way to do this is through a thowing closure that either returns a value or thows an error, as detailed in this blog post. However, this strikes me as odd as a closure can do anything and the desired behavior is very well defined. Through a simple extension to the familiar Result enum can serve this purpose. First here is the definition of a typical Result enum: enum Result centers Retired content Samples Developer Network Developer Sign in MSDN subscriptions Get tools magazine Issues and downloads All issues 2016 September 2016 August 2016 July 2016 June 2016 May 2016 April 2016 March 2016 February 2016 January 2016 2015 December 2015 November 2015 Windows 10 issue https://msdn.microsoft.com/en-us/magazine/jj991977.aspx October 2015 September 2015 August 2015 July 2015 June 2015 May 2015 April 2015 March 2015 February 2015 January 2015 2014 Special 2014 December 2014 November 2014 October 2014 September 2014 August 2014 July 2014 June 2014 https://appventure.me/2015/06/19/swift-try-catch-asynchronous-closures/ May 2014 April 2014 March 2014 February 2014 January 2014 2013 Government 2013 December 2013 November 2013 October 2013 September 2013 August 2013 July 2013 June 2013 May 2013 April 2013 March 2013 February 2013 January 2013 error handling 2012 December 2012 November 2012 Windows 8 October 2012 September 2012 August 2012 July 2012 June 2012 May 2012 April 2012 March 2012 February 2012 January 2012 2011 December 2011 November 2011 October 2011 September 2011 August 2011 July 2011 June 2011 May 2011 April 2011 March 2011 February 2011 January 2011 2010 December 2010 November 2010 October 2010 September 2010 August 2010 July 2010 June 2010 May 2010 April 2010 March 2010 February 2010 asynchronous error handling January 2010 2009 December 2009 November 2009 October 2009 September 2009 August 2009 July 2009 June 2009 May 2009 April 2009 March 2009 February 2009 January 2009 Subscribe Submit article We’re sorry. The content you requested has been removed. You’ll be auto redirected in 1 second. Issues and downloads 2013 March 2013 Async/Await - Best Practices in Asynchronous Programming March 2013 Volume 28 Number 03 Async/Await - Best Practices in Asynchronous Programming By Stephen Cleary | March 2013 These days there’s a wealth of information about the new async and await support in the Microsoft .NET Framework 4.5. This article is intended as a “second step” in learning asynchronous programming; I assume that you’ve read at least one introductory article about it. This article presents nothing new, as the same advice can be found online in sources such as Stack Overflow, MSDN forums and the async/await FAQ. This article just highlights a few best practices that can get lost in the avalanche of available documentation. The best practices in this article are more what you’d call “guidelines” than actual rules. There are exceptions to each of these guidelines. I’ll explain the reasoning behind each guideline so that it’s clear when it does and does not apply. The guidelines are summarized in Figure 1; I’ll discuss each in the following sections. Figure 1 Su & other technologies here. BENEDIKT TERHECHTE Follow @terhechte Fri, 19 Jun 2015 # Using try / catch in Swift with asynchronous closures With Swift 2.0, Apple introduced a new error handling model with the try, throw, and catch keywords. Given the sub par state of error handling in Swift 1.0, this was a welcome addition. It works basically as follows (simplified example): // We define a struct conforming to the new ErrorType enum Error : ErrorType { case DivisionError } func divide(a: Int, b: Int) throws -> Int { if b == 0 { throw Error.DivisionError } return a / b } do { let result = try divide(50, 10) } catch let error { print("Could not divide") } This is a nice and flexible way of structuring possible errors types and handling them. In synchronous code. But what about asynchronous operations? 1 An asynchronous operation Imagine the following operation as an example of any kind of asynchronous operation where there is a delay between the initiation of a computation and the result of the computation. In Objective-C land, this is solved with delegates, blocks or (though rarely) NSInvocation, in Swift the typical solution is a closure. func asynchronousWork(completion: (r: NSDictionary?) -> Void) -> Void { // do work ... completion(aDictionary) } How do you handle errors in these situations? We can expect, that within the asynchronousWork function most error handling will be via try/catch. So one possible solution that comes to mind is handling the errors in there, and only forwarding the result, if there is one: func asynchronousWork(completion: (r: NSDictionary?) -> Void) -> Void { NSURLConnection.sendAsynchronousRequest(request, queue: queue) { (response, data, error) -> Void in guard let data = data else { return } do { let result = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! NSDictionary completion(r: result) } catch _ { completion(r: nil) } } } // Call asyncSwift Closure Throws