Error propagation
Learn to propagate an error up the call chain by rethrowing it.
Error propagation
When you cannot handle an error in a catch block you rethrow it with throw err. The error travels up the call chain to the next layer, where it is caught. This is called error propagation. This way each layer handles only the errors it can solve and passes the rest up.
try {
saveOrder(order);
} catch (err) {
logError(err);
throw err;
} Wrapping errors with cause
To avoid losing the original error when rethrowing, you can wrap it using the cause option of a new error. This preserves the source error for debugging and adds context. You can reach the original error through the wrapped error's .cause property.
try {
fetchProfile(id);
} catch (err) {
throw new Error('Profile failed to load', { cause: err });
} Exercise Wrap and rethrow the error
Write a function saveOrder that takes an order parameter. In a try block call persist(order). In the catch block wrap the error with the cause option and rethrow it as new Error('Order could not be saved', { cause: err }).
Show example solution
function saveOrder(order) {
try {
persist(order);
} catch (err) {
throw new Error('Order could not be saved', { cause: err });
}
}
Test yourself
-
Rethrow the error
function safeSave(data) { try { persist(data); } catch (err) { ____ err; } }Show answer
function safeSave(data) { try { persist(data); } catch (err) { throw err; } } -
When should you rethrow an error in a catch block?
- When you want to hide it completely
- When you cannot handle it locally and want to pass it up
- When you just want to log and skip it
- When you want to skip the finally block
Show answer
When you cannot handle it locally and want to pass it up — Correct! Rethrowing an error you cannot handle passes it up.
-
Match propagation concepts
- throw err
- Passes error upward
- cause: err
- Keeps source error
- catch (err)
- Catches the error
- finally
- Runs cleanup either way