Skip to content
Theory · Errors · lesson 3 of 10

finally

Back to the chain of tasks. The intern takes a calculator from the desk and puts it back when done. But if the work fell through and he threw a note with the reason up the chain, he may forget the calculator. The next intern will come and not find it.

In a program this happens to variables that code changes for the time of its work. When an error is thrown in a try block, the lines after it do not run. If one of them was important, it is lost too. The function load parses JSON text and for that time sets a flag — the variable loading with the value true:

JavaScript
let loading = false;

function load(text) {
    loading = true;
    const data = JSON.parse(text);
    loading = false;
    return data;
}

try {
    load("{ bad");
} catch (e) {
    console.log("caught"); // caught
}
console.log(loading); // true

Let's see what happened:

  1. load set loading to true.
  2. JSON.parse threw a SyntaxError on the wrong text.
  3. The function stopped before the line loading = false.
  4. The catch outside caught the error and printed caught.
  5. The flag stayed true: the program thinks loading is still going on.

The finally block

After try and catch you can add a finally block. This is "putting the calculator back": the block runs whatever the outcome. There are three outcomes:

  • try finished without errors;
  • catch caught an error;
  • the error left the function.

So finally holds what must happen in any case. If catch runs, finally runs after it.

Most often finally undoes what the code did for the time of its work: it clears a flag or gives a counter back its old value.

JavaScript
function load(text) {
    loading = true;
    try {
        return JSON.parse(text);
    } finally {
        loading = false;
    }
}

Let's see what changed:

  1. loading = true still comes first in the function.
  2. Parsing the text moved into try, and clearing the flag into finally.
  3. There is no catch block here: the calling code catches the error from JSON.parse, as in the first example.
  4. Before the error leaves the function, finally clears the flag, and console.log(loading) prints false.

A try with finally and no catch is allowed, while a try with neither catch nor finally is not.

finally and return

finally is not skipped even when try ends with a return. The function remembers the value to return, then runs finally, and only after that does the calling code get the value:

JavaScript
function count() {
    try {
        console.log("try"); // try
        return 1;
    } finally {
        console.log("finally"); // finally
    }
}

console.log(count()); // 1

Let's look at the order of the lines:

  1. try prints try.
  2. return 1 remembers the result, but the function has not finished yet.
  3. finally prints finally.
  4. Only now does the outer console.log get 1 and print it last.

Interviewers often check this order: "Does finally run if try has a return?" It does, and before the calling code gets the value.

Here the intern picture stops working: a person can forget the calculator, but finally never forgets. Even a return in try does not cancel it.

Common mistake

A return is written in finally:

JavaScript
function load(text) {
    try {
        return JSON.parse(text);
    } finally {
        return null; // ✗
    }
}

There is no error message, but the function is broken. A return in finally replaces the value from try, so load('{"a":1}') returns null. It cancels a thrown error as well: for "{ bad" the function quietly returns null, and the catch outside gets nothing. Keep only actions such as loading = false in finally, with no return.

Key points

  • finally runs whatever the outcome: with no error, after catch, and when the error leaves the function.
  • finally puts back what the code changed for the time of its work, such as clearing a flag.
  • After a return in try, the finally block runs before the calling code gets the value.
  • A return in finally replaces the result and cancels a thrown error, so it is not written there.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way