Backend & Node.js · APIs, data and failure
How do you handle errors in a Node.js backend?
Short answer
Handle expected errors close to where they occur, propagate them with context, and use one central error handler for HTTP responses. Treat uncaught exceptions and unhandled rejections as fatal: log, clean up and exit.
Errors fall into two groups. Operational errors, such as a validation failure or a timeout, are expected and should produce a controlled response. Programmer errors, such as reading a property of undefined, indicate a bug and should not be silently swallowed. The handling strategy differs.
app.get("/users/:id", async (req, res, next) => {
try {
const user = await users.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: "not_found" });
}
res.json(user);
} catch (error) {
next(error);
}
});
app.use((error, req, res, next) => {
req.log.error({ error }, "request failed");
res.status(error.status || 500).json({ error: "internal_error" });
});Rules that prevent incidents
- Never send stack traces or internal messages to clients
- Attach context when rethrowing, including request or job identifiers
- Use error codes or typed errors instead of string matching
- Give every network call a timeout and treat cancellation as a normal outcome
- Do not retry non-idempotent operations without an idempotency key
At the process level, listen for unhandledRejection and uncaughtException, log the failure, stop accepting new work and exit. Continuing after an uncaught exception leaves the process in an unknown state, and a supervisor should restart it. Express 5 forwards rejected async handlers automatically, but explicit try and catch still makes intent clear.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What is the difference between operational and programmer errors?
- 2Should you restart after uncaughtException?
- 3How do you handle errors in a stream pipeline?
- 4How do you propagate a request ID through async calls?
Say it in the interview
I handle expected failures where they happen and forward unexpected ones to a single error handler that decides the response and logs context. I never leak stack traces to clients. At process level, an uncaught exception or unhandled rejection means the state is unknown, so I log, stop accepting work and exit for the supervisor to restart. Timeouts and cancellation are part of error handling too, not an afterthought.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Backend & Node.js mock interview and get scored feedback on depth, clarity and confidence.