Why does a return in `finally` override `try`?

Viewed 60495

How does a return statement inside a try/catch block work?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

I'm expecting the output of this function to be true, but instead it is false!

9 Answers

The finally block rewrites try block return (figuratively speaking).

Just wanted to point out, that if you return something from finally, then it will be returned from the function. But if in finally there is no 'return' word - it will be returned the value from try block;

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true

So -finally- return rewrites the return of -try- return.

I'm gonna give a slightly different answer here: Yes, both the try and finally block get executed, and finally takes precedence over the actual "return" value for a function. However, these return values aren't always used in your code.

Here's why:

  • The example below will use res.send() from Express.js, which creates a HTTP response and dispatches it.
  • Your try and finally block will both execute this function like so:
try {
    // Get DB records etc.
    return res.send('try');
} catch(e) {
    // log errors
} finally {
    return res.send('finally');
}

This code will show the string try in your browser. ALSO, the example will show an error in your console. The res.send() function is called twice. This will happen with anything that is a function. The try-catch-finally block will obfuscate this fact to the untrained eye, because (personally) I only associate return values with function-scopes.

Imho your best bet is to never use return inside a finally block. It will overcomplicate your code and potentially mask errors.

In fact, there's a default code inspection rule set-up in PHPStorm that gives a "Warning" for this:

https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html

So what do you use finally for?

I would use finally only to clean-up stuff. Anything that is not critical for the return value of a function.

It may make sense if you think about it, because when you depend on a line of code under finally, you are assuming that there could be errors in try or catch. But those last 2 are the actual building blocks of error handling. Just use a return in try and catch instead.

Returning from a finally-block

If the finally-block returns a value, this value becomes the return value of the entire try-catch-finally statement, regardless of any return statements in the try and catch-blocks

Reference: developer.mozilla.org

Related