Byte Corner

#javascript

•

3 min read

•

September 21, 2026

Why finally Runs Before return Takes Effect

A return does not immediately finish a function. finally gets one last chance to run, and can even change the result.

Matej Bošnjak
Matej Bošnjak

September 21, 2026

#javascript
#control-flow
#error-handling
Why `finally` Runs Before `return` Takes Effect

Why Your finally Runs After return

A return looks like the end of a function.

But put a finally after it:

function getValue() {
  try {
    return 42;
  } finally {
    console.log("cleanup");
  }
}

console.log(getValue());

The output is:

cleanup
42

The return happened.

The function just hadn't finished leaving yet.

🔴 The Problem

It's tempting to think of return as:

return
  ↓
function stops immediately

But with finally, there's another step.

When JavaScript reaches:

return 42;

it evaluates 42 and prepares to return it.

Before the function actually completes, JavaScript runs the finally block.

So the flow is roughly:

return 42
    ↓
remember 42
    ↓
run finally
    ↓
finish returning 42

The important part is that the return value has already been determined.

finally just gets to run before the function actually exits.

🟢 The Solution

This is exactly what makes finally useful for cleanup.

Imagine something that needs to be closed regardless of what happens:

function readFile(file) {
  try {
    return file.read();
  } finally {
    file.close();
  }
}

file.read() can still determine the value returned to the caller.

But file.close() runs before the function actually leaves.

Without finally, you'd have to duplicate the cleanup:

function readFile(file) {
  try {
    const result = file.read();

    file.close();

    return result;
  } catch (error) {
    file.close();

    throw error;
  }
}

With finally, the cleanup has one place:

function readFile(file) {
  try {
    return file.read();
  } finally {
    file.close();
  }

Whether try returns, throws, or finishes normally, finally gets its chance to run.

⚡ The Dangerous Part

finally isn't limited to cleanup.

It can actually change how the function finishes.

function getValue() {
  try {
    return 42;
  } finally {
    return 100;
  }
}

console.log(getValue());

The result is:

100

The original return 42 prepared the function to return 42.

Then finally executed another return.

That new return becomes the function's actual result.

The same thing can suppress an error:

function getValue() {
  try {
    throw new Error("Boom");
  } finally {
    return 42;
  }
}

console.log(getValue());

Instead of throwing, the function returns:

42

The return inside finally replaced the pending exception.

That's why returning from finally is usually a bad idea.

You're no longer just cleaning up.

You're changing the outcome.

🧠 The Takeaway

Don't think of:

return value;

as:

"I am completely done now."

Think of it as:

"I know how I want to finish."
        ↓
     finally
        ↓
"I actually leave now."

So this is perfectly reasonable:

try {
  return result;
} finally {
  cleanup();
}

But this deserves suspicion:

try {
  return result;
} finally {
  return somethingElse;
}

return decides the result.
finally gets the last chance to change how the function exits.

Back to all articles

Byte Corner

Byte Corner is still growing.

Not everything needs to be practical to be worth understanding. Sometimes you just find an interesting question and follow the rabbit hole.

const curious = true;

while (curious) {

keepDigging();

}

bytecorner

© 2026 bytecorner.dev

Small reads. Big understanding.