Mathieu Eveillard

You’re mistaken…

You’re mistaken…

Exception? Error? Are they one and the same? No!

Error and Exception: Two Very Different Concepts

Let’s take a moment to define each concept:

Exception Handling

Exceptions are easy to handle: we throw an exception and catch it at the highest possible level so that the program can continue running normally. We display a friendly little message (“Oops, something went wrong, we’ll be working on it soon so it doesn’t happen again!”) rather than cryptic messages like “ERR 30001C Attempt to use a closed socket,” and, most importantly, we log as much technical data as possible for the developers.

So what about errors?

At the risk of disappointing you, throwing an exception is the last thing you should do. Yes, I know—that’s what you’ve been taught ever since you were old enough to hold a keyboard—but no, three times no. Using exceptions to handle errors is pretty much like climbing onto the roof to get to the front of the train, walking the entire length of the train, and finally entering the lead car…

Error Handling: Railway-Oriented Programming

The problem is that throwing an exception interrupts the program’s normal flow of execution. In other words, the program is in PLS (Safety Lateral Position). This is odd, given that an error—as we’ve noted—is an error in the use of the program (1/0), an error in the context of the program’s use (network loss), but not an error in the program itself. So it will happen sooner or later.

This is all the more problematic in languages like TypeScript, which don’t require us to specify in a function’s signature that it might throw an exception. As a result, these functions are no longer “honest” (they don’t do what they say they will), and even less “pure.” And we don’t like that.

Ultimately, handling errors is a bit more complicated but remains entirely feasible. In practice, this involves defining an abstraction Result<T> that represents either success ({ type: "SUCCESS", result: T}) or an error ({ type: "ERROR", reason: string}). This forces us to do the same throughout the program and leads us straight to monads and Railway-Oriented Programming, beautifully explained by Scott Wlashing.

This topic is covered in detail in the course Functional Programming in Practice. As for the rest, exceptions should remain… the exception 😉

← All posts