Learn how to handle your errors and crashes gracefully in Swift with try catch blocks and more! You’ll see the most common error handling code samples below. If you’d like a longer read, check out the Swift error handling documentation.
Swift Try Catch
When you’re coding, you’ll see methods that have the throws
keyword. This indicates that the method may raise an error and as a best practice, you should gracefully handle the error and show an appropriate error message to the user. If you don’t catch the error, then your app will crash!
Here’s an example of the Swift do-try-catch
syntax:
do { // Create audio player object audioPlayer = try AVAudioPlayer(contentsOf: soundURL) // Play the sound audioPlayer?.play() } catch { // Couldn't create audio player object, log the error print("Couldn't create the audio player for file \(soundFilename)") }
Let’s walk through the code:
do
– This keyword starts the block of code that contains the method that can potentially throw an error.
try
– You must use this keyword in front of the method that throws. Think of it like this: “You’re trying to execute the method.
catch
– If the throwing method fails and raises an error, the execution will fall into this catch block. This is where you’ll write code display a graceful error message to the user.
Use this pattern to handle any potential errors caused by a method that throws
.
Using Try? and Try!
You can still call a method that throws
without using the do-try-catch
syntax.
// Create audio player object audioPlayer = try? AVAudioPlayer(contentsOf: soundURL) // Play the sound audioPlayer?.play()
If you use the try?
keyword instead of the basic try
, you’ll get nil
instead of the thrown error. In the code above, if the AVAudioPlayer
object can’t be created, then nil
will be assigned to the audioPlayer
variable.
Finally, if you’re 100% sure that there will be no error thrown, even though it’s a method that is marked as throws
, then you can use the try!
keyword instead of the basic try
.
// Create audio player object audioPlayer = try! AVAudioPlayer(contentsOf: soundURL) // Play the sound audioPlayer?.play()
Doing this will completely disregard the fact that an error might be thrown by the method and if an error actually occurs and you don’t have the do
catch
blocks, then your app will probably crash.
Creating your own Swift Error type
If you’d like to define your own error type, you can use an enum
and the Error protocol like this:
enum BankAccount: Error { case insufficientFunds case invalidTransaction case duplicateTransaction case unknown }
Throwing Errors
After you define your own error type, you can start using it in your methods like this:
func withdrawCash (amount: Int) throws { if funds - amount < 0 { throw BankAccount.insufficientFunds } else { funds -= amount } }
Using the throw
keyword, your method will return and raise the error. Notice that in your function declaration, you also need to indicate that the function can raise errors by specifying the throws
keyword.
When you throw the error, it’s like the return
keyword. Execution stops at the throw
keyword and returns to the caller.