xmedeko
xmedeko

Reputation: 7812

JavaScript try catch finally block change precedence of errors

Sometimes I have a code in try-catch-finally block when finally branch does some cleanup code which may throw an Error. An error in the finally branch suppresses a possible error in the main branch. I want exactly the opposite: see an error from the main branch always and an error from the finally branch only when the main branch proceeds without an error. I have came up with solution:

let thrownError = false;
try {
    doMainCode();
} catch (err) {
    thrownError = true;
    throw err;
} finally {
    try {
        doCleanUpCode();
    } catch (err) {
        if (!thrownError)
            throw err;
        console.error("Suppressed finally error", err);
    }
}

Which is cumbersome. Is there any simpler way how to change error precedence in try-catch-finally block?

Upvotes: 4

Views: 80

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074515

The usual approach I've seen here, for better or worse, is to just always suppress errors in the finally (dumping them to the console or a secondary logging stream or similar).

For places you don't want to do that, you could use a utility function to wrap your code to make it less cumbersome:

tryFinally(
    () => {
        // ...do main code...
    },
    () => {
        // ...do cleanup code...
    }
);

Yes, that does involve a layer of creating and calling functions where you didn't have one before, but modern JavaScript engines are very fast at that, it's not likely to cause a performance issue. (And if it does, you can address the specific places where it does.)

The tryFinally utility function would be responsible for handling the error stuff. Here's a quick sketch of an implementation:

function tryFinally(work, cleanup) {
    try {
        work();
    } catch (err) {
        try {
            cleanup();
        } catch (cleanupError) {
            console.error("Suppressed finally error", cleanupError);
        }
        throw err;
    }
    cleanup();
}

Upvotes: 2

Related Questions