Leaderboard
Javascript May 15, 2026
Javascript Return In Finally Block Overrides Try

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())
A "try"
B "finally"
C Both values
D undefined

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:

function test() {
  try {
    return "try"
  } finally {
    return "finally"
  }
}
console.log(test())

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:

function risky() {
  try {
    throw new Error("Something went wrong!");
  } finally {
    return "I saved the day";
  }
}

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:

async function fetchData() {
  setLoading(true);
  try {
    const data = await api.get('/user');
    return data;
  } catch (err) {
    handleError(err);
  } finally {
    setLoading(false); // This is the correct use: cleanup, not returning.
  }
}

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.

📝
Reviewed by CodeShot Editorial
Every challenge is code-reviewed by senior developers to ensure accuracy and real-world relevance. Learn more.

Ready for your shot?

Join thousands of developers solving one logic puzzle every morning.

Solve Today's Challenge →