Handling errors in JavaScript with try…catch and finally

JavaScript

Mistakes happen. That’s a given. According to Murphy’s law, whatever can go wrong, will go wrong. Your job, as a programmer, is to be prepared for that fact. You have a set of tools that are prepared to do precisely that. In this article, we go through them and explain how they work.

An error

When a runtime error occurs, a new error object is created and thrown. The browser presents you with the file name and the line number in which the problem occurs. Time for some evildoing:

I’ve put that code into my DevTools console and got that:

uncaught reference error

The thing that you might find striking here is the  . If you look it up in the chromium source code you discover that it has no special meaning and occurs if your code is not tied to a particular file. The same thing happens if you are using eval (which you probably shouldn’t do!). Otherwise, it is the name of the file in which the error occurs.

In this example, the ReferenceError is the message name and cosnole is not defined is the message.

Since we refer here to throwing the error, how about we catch it?

Try & catch

If an error is thrown inside of the try block, the execution of the rest of the code is stopped. The error is caught so that you can deal with it inside of the catch block. If no exceptions are thrown in the try block, the catch is skipped.

Even though back in the days all declared variables used to have a functional scope (since they were declared using the var keyword, not with const and let), the catch statement is an example of block scope. The catch block receives an identifier called error in the example above. It holds the value of what was thrown in the try block. Since it is a block-scoped, after the catch block finishes executing, the error is no longer available.

If you would like to know more about variable declarations in JavaScript, check out Scopes in JavaScript. Different types of variable declarations 

An important thing to keep in mind is that if you don’t provide a variable name for the error in the catch statement, an error is thrown!

Try…catch works only for runtime errors. If the error comescame from the fact that your code is not valid JavaScript, it won’t be caught.

Asynchronous code

The try…catch mechanism can’t be used to intercept errors generated in asynchronous callbacks. This fact is a common source of a misunderstanding.

Uncaught ReferenceError: cosnole is not defined at setTimeout

It does not work because the callback function passed to the setTimeout is called asynchronously. By the time it runs, the surrounding try…catch blocks have been already exited. You need to put them in the callback itself.

It is a lot better if you use promises.  You can catch your errors using the catch function:

If you would like to know more about promises and callbacks check out Explaining promises and callbacks while implementing a sorting algorithm

The try…catch blocks make a comeback to deal with asynchronous code if you use async/await

If you are interested in async/await, read Explaining async/await. Creating dummy promises

Finally

There is one more clause that you can use, and it is finally. It will execute regardless of whether an exception is thrown.

If you use the try block, you need to follow it with either the catch statement, the finally block or both. You might think that the finally statement does not serve any purpose, because you can write code just under the try…catch block. The fact is it is not always going to be executed. Examples of that are nested try-blocks.

In this example, the   is not executed, because control is immediately transferred to the outer try’s catch-block. The finally is executed first even in such a case.

For more examples on how finally works, check out the code presented on MDN.

Throwing exceptions

JavaScript allows us to throw our own exceptions using the throw keyword. There is no restriction on the type of data that you throw.

The Error object

The error that gets thrown when the runtime error occurs inherits from Error.prototype and consists of two properties: the name of the error and the message. The name can be one of the predefined types of errors or a custom one.

The Error.prototype.constructor accept one argument, and it is the error message. If you would like to throw a non-generic error, you can use one of the predefined ones, or define a new one! To do this, you can use ES6 classes:

As you can see, the name of the error is now MyError. In Chrome it would be named after you class anyway, even without doing  , but it might not work that way in other browsers. When an error is thrown, most browsers display a whole stack so that you can see what exactly happen:

The Error.protototype.stack is non-standard, but it is implemented both by Chrome and Firefox.

Since it is not standardized, it behaves differently across browsers, so watch out!

Summary

In this article, we went through handling errors in JavaScript. It included describing how errors work in JavaScript and how to throw them. We’ve also covered the try…catch block and what purpose can the finally block serve. Aside from that, we’ve also explained the Error object in JavaScript and what are its properties, including some non-standardized ones. Hopefully, this will help you handle your errors better.

Comments (1)

Leave a Reply

Your email address will not be published. Required fields are marked *