Error handling in swift
Error handling is the process of responding to and recovering from error conditions in your program. In many situations we may have to deal with errors. Sometimes we also have to let the co-workers know that the program throws error. I will try to explain every aspects of error handling here in this article.
I had a hard time handling errors. I read more about what a do-try
block is, and the difference between a try
, try!
, and try?
.
As an example, consider the task of reading and processing data from a file on disk. There are a number of ways this task can fail, including the file not existing at the specified path, the file not having read permissions, or the file not being encoded in a compatible format. Distinguishing among these different situations allows a program to resolve some errors and to communicate to the user any errors it can’t resolve.
In Swift, errors are represented by values of types that conform to the
Error
protocol.
Consider the above example of reading a file . If you use if -else statements for error handling, it will be something like this:
func readFiles(path:String) ->String {if fileNotFound {print(“fileNotFound”)} else if fileNotReadable {print(“fileNotReadable”)} else if fileSizeIsTooHigh {print(“fileSizeIsTooHigh”)}return “Data from file”}
Here, if we want to transfer the control back to the function call and to inform that something unexpected happened, we need to have a throwable function.
Error Handling
is just additional way to write anelse-if
statement to not only deal with the error messages but also respond after them in a separate block.
Swift enumerations are particularly well suited to modeling a group of related error conditions, with associated values allowing for additional information about the nature of an error to be communicated. Create an enum with the possible errors. The enum should confirm to the error protocol.
enum ErrorsToThrow: Error {case fileNotFoundcase fileNotReadablecase fileSizeIsTooHigh}
Design A Throwable Function
Create a function that can throw/return errors by inserting throws
at the end of the function parameter. The function does not contain error messages. Instead, it "throws" an error which will be "caught" and handled in a separate block with do-try
.
According to apple docs: To indicate that a function, method, or initializer can throw an error, you write the
throws
keyword in the function’s declaration after its parameters. A function marked withthrows
is called a throwing function. If the function specifies a return type, you write thethrows
keyword before the return arrow (->
).
func canThrowErrors() throws -> Stringfunc cannotThrowErrors() -> String
Let’s rewrite the above readFiles(path:)
as a throwable function.
func readFiles(path:String) throws ->String {if fileNotFound {throw ErrorsToThrow.fileNotFound} else if fileNotReadable {throw ErrorsToThrow.fileNotReadable} else if fileSizeIsTooHigh {throw ErrorsToThrow.fileSizeIsTooHigh}return “Data from file”}
When an error is thrown, some surrounding piece of code must be responsible for handling the error — for example, by correcting the problem, trying an alternative approach, or informing the user of the failure.
To call a function that contains throws
, the function requires try
within a do-catch
block. A catch
block is used to recognize and the error thrown by the function. If there is no error thrown, the catch
block is ignored.
do {let dataFromString = try? readFiles(path: “path for file”)} catch ErrorsToThrow.fileNotFound {print(“fileNotFound”)} catch ErrorsToThrow.fileNotReadable {print(“fileNotReadable”)} catch ErrorsToThrow.fileSizeIsTooHigh {print(“fileSizeIsTooHigh”)}
There are four ways to handle errors in Swift:
— You can propagate the error from a function to the code that calls that function.
— Handle the error using a do
-catch
statement.
— Handle the error as an optional value (try?).
— Assert that the error will not occur (try!).
When a function throws an error, it changes the flow of your program, so it’s important that you can quickly identify places in your code that can throw errors. To identify these places in your code, write the try
keyword—or the try?
or try!
variation—before a piece of code that calls a function, method, or initializer that can throw an error.
The performance characteristics of a
throw
statement are comparable to those of areturn
statement.
Initializers that throws :
Throwing initializers can propagate errors in the same way as throwing functions. Consider a Human
class that has an initializer that throws and error. When the user enters an empty string when initializing, the init method throws ErrorsToThrow.nameIsEmpty
from the following enum.
enum ErrorsToThrow: Error {case nameIsEmpty}
The Human
class should be like:
class Human {var name:String?init(name:String?) throws {guard let name = name else {throw ErrorsToThrow.nameIsEmpty}self.name = name}}
Create an object using try
within a do-catch
block.
do {let humanObj = try Human(name: nil)} catch ErrorsToThrow.nameIsEmpty {print(“The name is empty.Cannot initialize human”)}// prints The name is empty.Cannot initialize human
try vs try! vs try?
try
is only used within ado-catch
block. However,try?
andtry!
can be used without it.
— try?
returns an optional type. It can be used without a do-catch
block. If the method of initializer throws an error, the result will be nil.
Consider we are initializing the Human
object using a try?
keyword.
let humanObj1 = try? Human(name: “He-man”) // returns Human?let humanObj2 = try? Human(name: nil) // nil (humanObj2 is an optional which can handle nil)
— try!
It returns a normal type. If the method/init throws an error, it will crash. Because the returned type will be nil and a normal type cannot handle nil.
let humanObj1 = try! Human(name: “He-man”) // returns Humanlet humanObj2 = try! Human(name: nil) // nil and the app will crash
Again, avoid using
!
in most cases since it will break your program.
Recommended articles for you:
Enjoy!!
If you enjoyed reading this post, please share and recommend it so others can find it 💚💚💚💚💚💚 !!!!
You can follow me on Medium for fresh articles. Connect with me on LinkedIn.
If you have any comment, question, or recommendation, feel free to post them in the comment section below!