Swift 2.0 brought us
ErrorType. Let’s take a brief look on it.
I believe this protocol is implemented by every error type in Apple’s frameworks. There is no documentation for this protocol so far, just a page for it with notice that this is preliminary document and by which other types this one is adopted.
Protocol declaration and its extension is pretty much simple like the documentation, meaning, it is empty.
It is empty but enums, error-like classes/structs have to implement it to be able to throw them in methods.
throws is nice addition to Swift, it makes methods declaration simpler and
error handling easier.
In Objective-C method declaration which might return error look like this
In Swift older than Swift 2.0 it changed a bit to
error parameter is not declared as optional but it may take nil. It is possible
NSErrorPointer is just typealias of
AutoreleasingUnsafeMutablePointer as inline documentation comment says
is just mutable pointer to Objective-C pointer argument. It may take nil or
inout argument of referenced type.
To call such method in Swift you need to pass nil or create variable of type
and pass it by reference using
& operator (
&err) and you can get some
Bool value from a method as well as error object if returned - How many times did
you just pass nil in Objective-C because you didn’t want to handle errors because
of increased code complexity?! :> … I thought that you answered “0 times,
I always handle errors.” :)
throw and ErrorType in use
It was always the case that when something failed in such kind of method then
it returned false and filled passed error variable or just return true and
error was nil. Apple figured that out it could be improved. They added
in Swift 2.0.
In Swift 2.0 the method might be defined as
It means, that it returns
Bool or throws if something goes wrong. The method
declaration could be even simpler in this case, since we expect that method throws
which means something went wrong or returns
Bool which is always true if
returned which means success - the return type can be dropped.
throws forces us to use
do-catch around the code that can throw errors.
Let’s pretend we’ve got secure store which is somewhere in an app directory and
SecureStore class to store data inside. There is a method which
NSData object and path to a directory where this data will be stored.
It returns identifier of stored data if successfully saved or throws an error.
Here is possible declaration of such method:
Let’s say method just throws some error if something went wrong,
example. To execute the method it has to be around do-catch.
But that’s not all.
NSError needs some error domain and code to be defined.
We can use
ErrorType protocol and create own errors, e.g. using enums.
Let’s define some enumeration which implements
ErrorType protocol so it can
be throw by our method.
Handling could look like this:
You can omit
do-catch by calling a method with
try! instead of
You can do this when you’re sure that your specific case of calling the method
will not throw errors. It disables error handling and if any error occurs it
will end with runtime error and crash of your code. Use it carefully!
But, how the method look inside? How to throw? What with the value that method returns? Here is simple implementation of above method.
So new error handling works well in synchronous code. Unfortunately we’re not
able to use do-catch and handle errors the same way with asynchronous code because
the method returns/ends before asynchronous operation ends. There is no best
solution for this (at least for now), we can use some kind of
Result enum which
will wrap errors in case of failure and returned value in a case of success.
Here is good example of our
So, as you can see it reminds a bit Objective-C’s way of handling errors in
asynchronous code. There is a private
loadingLogicGoesHere method which is
do-catched inside and then the error is passed via
Result enum to the block
which handles all the errors and does specific things for them. I tried to
figure out a better solution but do not have idea. I browse Apple Developer Forums
and found this topic where person with nick mmm suggested a nice way
to solve this problem in Swift. I like it, we’ll see whether this will be live
with next updates or not (The post is 2 months to date).
UPDATE 2: Charlag Khan replied on my tweet and wrote there is another way we can tackle with asynchronous error handling.
Jeremy figured out that if function call can throw we can pass the function as
parameter to a callback and execute it in the block and handle error there.
This let us drop this
Result struct presented above and simplify
ErrorType are nice additions to the Swift 2.0.
I believe it will makes our code easier to read, understand and debug without
thinking if error will be returned or not if there is some other thing returned
by the method like in example above. It creates nice separation between success
and failure scenarios, handling is clearer than with
NSError floating around
the method in Objective-C.
It still needs some additional work to make it more consistent in terms of
handling synchronous and asynchronous code. Would be nice to not have to use
any additional transfer data enums like
Declaring own error types and errors is very easy. We do not need to subclass
or wrap it somehow, just create simple enum that implements
and it is ready to use.