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?
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();
}