I was just working on a side project, writing some code and at some point I needed to throw an exception.
Exceptions are a programming language construct that’s used to signal errors. Let’s entertain this example. There’s a function that takes two parameters, divides them and returns the result. Now, dividing by zero is not allowed and we’d like to make sure that this is not possible.
function divide(a, b) {
return a / b;
}
(I know that the programming language (in this case JavaScript) is already checking for that but it’s a good example that doesn’t require too much additional context.)
With an exception we can tell the rest of the program that we can’t perform the calculation. Let’s have a look at how this works:
function divide(a, b) {
if ( b == 1 ) {
throw "Cannot divide by zero";
}
return a / b;
}
throw is part of the language syntax (as in many other languages). It causes the program to stop executing the current function and leaves it immediately, like a return statement but without returning any value. Also, the place it returns to might be different. More on that in a second.
What happens next? An exception bubbles up the so-called call stack until it’s caught.
The Call Stack keeps track of which function calls what function, so that whenever you call a function in your code like var result = divide(15, 3); the code knows where to come back to once divide has been executed successfully.
Now, catching an exception looks like this:
try {
var result = divide(15, 3);
}
catch(err) {
console.err(err);
}
The try / catch mechanism is also part of the language’s syntax. When divide goes wrong because I passed a zero as second argument, then the exception is handled in the catch clause.
Why is all of this necessary though?
Think of it like this: Sometimes, you find out that something doesn’t work out because the data you’ve received. The problem is, at that place you might not necessarily know what to do about this and therefore you escalate the situation by throwing an exception. I’ve worked in customer support for a while and there were situations I could handle myself perfectly but when a customer wanted a refund I needed to talk to my manager to get permission. On a high level, exceptions are similar to that.
To make things more interesting, there are different types of Exceptions that you can use. Why’s that?
To explain that, let’s consider this: There are expected and unexpected errors.
An unexpected error could be an ArgumentError that occurs when a variable was null or undefined even though it was supposed to point to an object. It is expected / okay that the program crashes because of that, since it wasn’t supposed to happen in the first place. As developers, it is our responsibility to fix these errors, making sure that the object that was null or undefined is valid.
An expected error on the other hand would be something like a ValidationError for a form. The user submitted a form that wasn’t valid (like missed to fill out a field). In that case, the error needs to be caught and handled by the application. Handling it can mean to not process the form and show an error message to explain to the user what went wrong.
Exceptions are used in a lot of languages. In this example, I’ve used JavaScript but other languages such as Java, Ruby, Python and C# also use it. Though, it’s not the only way of communicating errors. C and Rust have other mechanisms for signaling and handling errors. Let me know if that sounds interesting to you too.