TL;DR
Proper error handling and logging make debugging, monitoring and maintenance easier. In 2026 use structured logs, levels (info, warn, error) and central collection (e.g. Sentry, Datadog). Here are the practices.
Who this is for
- Backend and full-stack developers
- Teams setting up monitoring and alerting
- Anyone who wants to avoid apps failing silently
Keyword (SEO)
error handling, logging, structured logs, monitoring, node.js, best practices
Why Error Handling and Logging?
- Debugging – quickly find the cause (stack trace, context)
- Monitoring – alerts on critical errors, metrics
- Audit – who, when, what (e.g. request logs, change logs)
- UX – user sees a clear message instead of a blank screen
Error Handling Rules
- Don’t swallow errors – avoid empty
catchwithout logging - Distinguish error types – expected (e.g. validation) vs unexpected (bug) – different handling
- Return safe messages – in API don’t expose stack trace to client; log full details internally
- Use HTTP status codes – 400 (bad request), 401 (unauthorized), 404, 500 (server error)
Log Levels
- error – errors that need action (exception, failed request)
- warn – unexpected but app still works (deprecated API, retry)
- info – important events (start/stop, deploy, key operations)
- debug – details for debugging (dev/staging only)
In production usually: info, warn, error; no debug (too much data).
Structured Logs (JSON)
Instead of plain text “User 123 failed” use:
{
"level": "error",
"message": "Login failed",
"userId": "123",
"reason": "Invalid password",
"timestamp": "2026-01-29T12:00:00Z"
}
Easier to search and aggregate in tools (ELK, Datadog, CloudWatch).
Example: Node.js / Next.js API
// Middleware or global error handler
function logError(err, req) {
logger.error({
message: err.message,
stack: err.stack,
path: req?.path,
method: req?.method,
});
}
// In API route – don’t send stack to client
try {
await doSomething();
} catch (err) {
logError(err, request);
return Response.json(
{ error: 'Something went wrong' },
{ status: 500 }
);
}
Checklist / steps
- Use a single logger (e.g. Pino, Winston) with levels
- Log errors with context (request id, user id, path)
- In production don’t return stack trace in API response
- Add error collection (Sentry, LogRocket) for frontend and/or backend
- Set alerts on error level (Slack, email, PagerDuty)
FAQ
Should I log every request?
Depends. High-traffic API – often only errors and selected metrics. Lower traffic – you can log every request (info) with duration. Never log passwords or tokens.
Sentry vs own logs?
Sentry focuses on errors and their context (release, user, breadcrumbs). Own logs – full control over format and storage. In practice both: Sentry for errors, logs for audit and metrics.
How to avoid leaking data in errors?
In client response return a generic message (“Something went wrong”). Stack trace, file paths, queries – only in logs and internal tools.