syntax Copy
try { ... }
catch (error) { ... }
finally { ... }example Copy
function parseConfig(jsonString) {
try {
return JSON.parse(jsonString);
} catch (error) {
console.error("Invalid config JSON:" , error.message);
return {};
} finally {
console.log("Config parsing attempted." );
}
}
const config = parseConfig('{"debug": true}' );
console.log(config);output
"Config parsing attempted."
{ debug: true }Note finally always runs, whether the try succeeded or catch was triggered. It even runs if try or catch contains a return statement.
try catch error handling finally catch error exception handling
syntax Copy
throw new Error(message);
throw new TypeError(message);example Copy
function withdraw(account, amount) {
if (amount <= 0 ) {
throw new RangeError("Withdrawal amount must be positive" );
}
if (amount > account.balance) {
throw new Error("Insufficient funds" );
}
account.balance -= amount;
return account.balance;
}Note Always throw Error objects (not strings) so you get a stack trace. Use specific error types (TypeError, RangeError) when appropriate.
throw error raise exception custom throw throw new Error
syntax Copy
class CustomError extends Error {
constructor(message) {
super (message);
this .name = "CustomError" ;
}
}example Copy
class ValidationError extends Error {
constructor(field, message) {
super (message);
this .name = "ValidationError" ;
this .field = field;
}
}
class NotFoundError extends Error {
constructor(resource, id) {
super (`${resource} with id ${id} not found` );
this .name = "NotFoundError" ;
this .resource = resource;
this .id = id;
}
}
try {
throw new ValidationError("email" , "Invalid email format" );
} catch (err) {
if (err instanceof ValidationError) {
console.log(`Field: ${err.field}, Message: ${err.message}` );
}
}output
"Field: email, Message: Invalid email format"Note Custom errors let you add context (which field, which resource) and enable precise catch handling with instanceof checks.
custom error extend Error error class typed error application error
Error Cause (error.cause) syntax Copy
throw new Error(message, { cause: originalError });example Copy
async function loadUserData(userId) {
try {
const res = await fetch(`/api/users/${userId}` );
return await res.json();
} catch (err) {
throw new Error("Failed to load user data" , { cause: err });
}
}
try {
await loadUserData(42 );
} catch (err) {
console.error(err.message);
console.error(err.cause?.message);
}Note The cause option (ES2022) lets you wrap errors while preserving the original. Essential for debugging errors that propagate through layers.
error cause chain errors wrap error error context original error
syntax Copy
TypeError | RangeError | ReferenceError | SyntaxError | URIError | EvalError | AggregateErrorexample Copy
try { null .toString(); }
catch (e) { console.log(e.constructor.name); }
try { new Array(-1 ); }
catch (e) { console.log(e.constructor.name); }
try { console.log(undeclaredVar); }
catch (e) { console.log(e.constructor.name); } Note Catching specific types helps you handle known errors differently from unexpected ones. AggregateError wraps multiple errors (used by Promise.any()).
error types TypeError RangeError ReferenceError built-in errors
syntax Copy
try { ... } catch { ... }example Copy
function tryParseJSON(str) {
try {
return JSON.parse(str);
} catch {
return null ;
}
}
console.log(tryParseJSON('{"valid": true}' ));
console.log(tryParseJSON("not json" )); Note Since ES2019, you can omit the error parameter in catch if you do not need it. Keeps code cleaner for "swallow and fallback" patterns.
optional catch catch without parameter ignore error variable
Centralized Async Error Handling syntax Copy
process.on('unhandledRejection' , handler)
window.addEventListener('unhandledrejection' , handler)example Copy
window.addEventListener("unhandledrejection" , (event) => {
console.error("Unhandled rejection:" , event.reason);
event.preventDefault();
reportToService(event.reason);
});
process.on("unhandledRejection" , (reason, promise) => {
console.error("Unhandled rejection at:" , promise, "reason:" , reason);
});Note Global handlers are your safety net -- they should log and report, not silently swallow errors. Always prefer local try/catch for known async operations.
unhandled rejection global error handler catch all errors error reporting
Working with Stack Traces syntax Copy
error.stack
error.message
error.nameexample Copy
function deepFunction() {
throw new Error("Something broke" );
}
try {
deepFunction();
} catch (err) {
console.log(err.name);
console.log(err.message);
console.log(err.stack);
}Note err.stack is not standardized but is supported everywhere in practice. It includes the error message and the call chain leading to where the error was created.
stack trace error stack debug error error message error properties