Error Handling
Catch and handle errors so your app fails gracefully.
Syntax
try { await task(); } catch (err) { ... }Robust apps expect things to go wrong. Handle errors deliberately rather than letting them crash the process.
Techniques
- Wrap
awaitcalls intry...catch. - Check
errfirst in callbacks. - Listen for a stream's
'error'event.
Last resorts
Handle uncaughtException and unhandledRejection to log fatal errors — then exit, because the app may be in a broken state.
Example
async function safeParse(text) {
try {
return JSON.parse(text);
} catch (err) {
console.error('Invalid JSON:', err.message);
return null;
}
}
console.log(safeParse('{"ok":true}')); // { ok: true }
console.log(safeParse('not json')); // nullWhen to use it
- An Express API uses a centralized error-handling middleware `(err, req, res, next)` so every thrown error returns a consistent JSON response without duplicating try/catch in every route.
- A background job wraps each task in a try/catch and logs the error with context before marking it as failed, so the queue can retry it later.
- A Node.js process registers a `process.on('uncaughtException')` handler to log fatal errors and shut down gracefully instead of crashing silently.
More examples
Custom error class
Extends `Error` with a custom class so thrown errors carry a semantic status code alongside the message.
class AppError extends Error {
constructor(message, statusCode = 500) {
super(message);
this.name = 'AppError';
this.statusCode = statusCode;
}
}
throw new AppError('User not found', 404);Async error propagation
Catches errors from async functions and passes them to Express error-handling middleware with `next(err)`.
async function getUser(id) {
const user = await db.findById(id);
if (!user) throw new AppError('Not found', 404);
return user;
}
// In an Express route:
router.get('/users/:id', async (req, res, next) => {
try {
const user = await getUser(req.params.id);
res.json(user);
} catch (err) {
next(err); // forward to error middleware
}
});Global uncaught error handlers
Registers last-resort handlers for uncaught exceptions and unhandled promise rejections to log and exit cleanly.
process.on('uncaughtException', (err) => {
console.error('Uncaught:', err);
process.exit(1); // always exit after uncaught
});
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection:', reason);
process.exit(1);
});
Discussion