Handling multiple errors

Since you’re a smart developer, you’ve noticed that you’re not handling errors in goHome. Instead, you’ve marked that function with throws as well, leaving the error handling up to the caller of the function.

Because every movement can throw an error, your error handling code can quickly grow out of control. You might benefit from a function that can move the PugBot and handle errors at the same time:

func moveSafely(move:() throws -> ()) -> String { do {

try move()

return "Completed operation successfully."

} catch PugBotError.invalidMove(let found, let expected) {

return "The PugBot was supposed to move (expected), but moved \ (found) instead."

} catch PugBotError.endOfPath() {

return "The PugBot tried to move past the end of the path."

} catch {

return "An unknown error occurred"

}

}

This function takes a movement function, or a closure containing movement function calls, as a parameter, calls it and handles any errors that might be thrown.

You might notice that you have to add a default case at the end. What gives? You’ve exhausted the cases in your PugBotError enum, so why is the compiler hassling you?

Unfortunately, at this point, Swift’s do-try-catch system isn’t type-specific. There’s no way to tell the compiler that it should only expect PugBotErrors. To the compiler, that isn’t exhaustive, because it doesn’t handle each and every possible error that it knows about, so you still need to have a default case.

Now you can use your function to handle movement in a safe manner:

moveSafely {

try pug.moveForward() try pug.turnLeft() try pug.moveForward() try pug.turnRight()

}

Thanks to trailing closure syntax, your movement calls are cleanly wrapped in the call to moveSafely(_:). Here, your PugBot will find her way home safely.

results matching ""

    No results matching ""