It’s frozen over in Scotland just now – I’ve literally been inside my house for a week solid due to the snow! It’s so thick that supplies are running thin, so I thought I would make a blog about throwing errors in Swift, naturally.

Let’s make some error cases:


1
2
3
4
5
enum CustomError: Error {
  case foodError
  case milkError
  case cabinFeverError
}

Pretty standard stuff for enum cases, like having now food or being locked up way too long in the house!


1
2
3
func tryError(_ checkIfIAmOkay: () throws -> ()) rethrows {
  try checkIfIAmOkay()
}

Here we have the ‘rethrows’ keyword. Now if a function you write can potentially throw an error then it has to be marked with ‘throws’. You would then call that function in a ‘do/catch’ statement, sort of like what you do when de-serialising JSON from data. The idea behind it is that it could fail the de-serialisation process so it needs error handling.

What does ‘rethrows’ mean then? Well you’ll notice that the closure checkIfIAmOkay passed in (affectionately named after being locked up with the kids for a week in the cold haha) can potentially throw an error, so we have to mark the function as rethrows. What we’re basically saying is: ‘Hey, this closure I’m passing in, it does some stuff that might cause an error, so you function that is in control of this, you need to also need to be aware of that and handle any errors that come your way’. 

Essentially any closure that throws needs it’s calling function to be marked as ‘rethrows’.

Let’s call this here:


1
2
3
4
5
6
7
8
9
10
11
do {
  tryError {
    // Do stuff in here
  }
} catch let error as CustomError {
  if error == .foodError {
    print("Ran out of Milk due to Snow")
  } else if error == .cabinFeverError {
    print("Get me out of here")
  }
}

You’ll be glad to know I’m coping just fine haha!