JavaScript Try...Finally — Which Value is Returned?
This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Return In Finally Block Overrides Try and improve your technical interview readiness.
function test() {
try {
return "try"
} finally {
return "finally"
}
}
console.log(test())
Detailed Explanation
Why This Question Matters
If you've ever spent an hour debugging a function that seems to be returning the wrong value despite a clear return statement, you've probably run into the weirdness of the finally block.
Most of us learn try...catch...finally as a way to handle errors and clean up resources—like closing a database connection or hiding a loading spinner. We're taught that finally *always* runs, regardless of whether an error occurred. But there's a specific edge case that catches a lot of developers off guard: what happens when you actually return a value from inside that finally block?
It feels counterintuitive. You'd think the first return encountered would end the function execution. But JavaScript handles this differently, and understanding this behavior is the difference between writing predictable code and chasing ghosts in your debugger.
Understanding the Code
Let's look at the snippet again:
At first glance, you might think, "Okay, it hits the try block, returns 'try', and the function ends." But that's not how the JavaScript engine processes this.
Here is the internal play-by-play:
1. The engine enters the try block.
2. It encounters return "try".
3. Now, the engine *sets aside* that return value. It doesn't actually exit the function yet because it sees a finally block waiting.
4. The engine jumps into the finally block to perform the mandatory cleanup.
5. Inside finally, it hits return "finally".
Because the finally block is designed to be the absolute last word in the execution flow, any return statement inside it overwrites any previous return values or even thrown errors from the try or catch blocks.
Finding the Correct Answer
The output of this code is "finally".
Why? Because the finally block effectively "hijacks" the return process. When the try block returns "try", JavaScript essentially says, "I'll remember that value for a second, but I have to run the finally block first." Once the finally block executes its own return statement, it replaces the previous value entirely.
If the finally block didn't have a return statement, the function would have gone back and returned "try". But since it does, the first return is simply discarded.
Common Mistakes Developers Make
The biggest mistake is assuming that finally is just for "side effects" (like logging or closing files) and that it can't alter the function's output.
Another tricky scenario happens when you throw an error. Look at this:
In a normal scenario, this function should throw an exception. But because of that return in the finally block, the error is silently swallowed. The function will return "I saved the day", and the error disappears into the void. This is a dangerous pattern because it makes debugging nearly impossible—your code is failing, but the function is returning a successful value.
Real-World Usage
In a production environment, you should almost never return a value from a finally block. It's generally considered a bad practice because it creates unpredictable control flow.
The correct way to use finally is for cleanup logic that doesn't interfere with the function's result. For example, managing a UI state in a React component or a Node.js file stream:
In the example above, setLoading(false) runs whether the request succeeded or failed, but it doesn't overwrite the data being returned or the error being handled.
Key Takeaways
- The finally block always executes, no matter what happened in the try or catch blocks.
- If you return inside a finally block, that value overrides any other return value or thrown error in the function.
- Returning from finally can accidentally swallow exceptions, making your code harder to debug.
- Use finally for cleanup (closing connections, resetting state), not for controlling the function's return value.
Why this matters
Understanding Return In Finally Block Overrides Try is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.