Advanced - ds-express-errors
Global Exception Handlers
Node.js apps can crash due to uncaughtException or unhandledRejection.initGlobalHandlers catches these process-level errors, logs them, and allows for a graceful shutdown (closing DB connections, server sockets, etc.).
Basic Usage
Initialize this at the entry point of your application (e.g., `index.js`).
import { initGlobalHandlers } from 'ds-express-errors';
// Will log the error and process.exit(1)
initGlobalHandlers();Graceful Shutdown & Global Handlers
Read more about graceful shutdownDS Express Errors provides a robust way to handle application crashes and termination signals (SIGINT, SIGTERM). It ensures your server stops accepting new connections and finishes active requests before exiting.
Work from v1.5.0+:
initGlobalHandlersnow supports full graceful shutdown:- Asynchronous
onCrash(error, signal)is automatically awaited with a default 10-second timeout. (or you can setmaxTimeoutto change it) The library callsprocess.exit(1)after it completes, so you no longer need to exit manually. - New onShutdown(signal) handler for normal shutdowns (
SIGTERM,SIGINT,SIGQUIT). - Support for
closeServer(signal)to safely close an HTTP server, including handling AbortSignal. - Built-in safeShutdown prevents repeated shutdown calls and logs forced exits (Forced exit from graceful shutdown).
- Timeout and AbortSignal are applied to all long-running async operations to avoid blocking process exit.
import { initGlobalHandlers, gracefulHttpClose } from 'ds-express-errors';
const server = app.listen(3000);
initGlobalHandlers({
closeServer: gracefulHttpClose(server), // Gracefully close server
onShutdown: async (signal) => {
console.log('Cleaning up...');
await mongoose.disconnect(); // Close DB connections
},
onCrash: async (err, signal) => {
await sendAlertToAdmin(err); // Notify dev team about crash
}
});Custom Response Formatting
Read more about configurationBy default, the library sends responses in a standard format (`status`, `message`, `url`). You can completely override this structure using the setConfig method.
{
"status": "error", // or 'fail'
"method": "GET", //dev only
"url": "/api/resource", //dev only
"message": "Error description",
"stack": ... //dev only
}Operational vs. Programmer Errors
The library distinguishes between two types of errors using the isOperational flag:
- Operational Errors (
isOperational: true): Expected runtime problems (e.g., "User not found", "Validation failed"). The application can continue running. All Presets result in operational errors. - Programmer Errors (
isOperational: false): Bugs in the code (e.g.,TypeError,SyntaxError, trying to access undefined). The best practice is to crash and restart the app to avoid inconsistent state.
The global handler logs Operational: false errors with high severity.
Creating Custom Error Classes
You can extend AppError to create domain-specific errors for your application.
import { AppError } from 'ds-express-errors';
class SubscriptionExpiredError extends AppError {
constructor(message = 'Your subscription has expired') {
// Pass message and 402 (Payment Required) status
super(message, 402, true);
}
}
// Usage in controller
app.post('/premium-content', (req, res, next) => {
if (user.subscriptionStatus === 'expired') {
throw new SubscriptionExpiredError();
}
});Have some ideas? Find something missing? or Bug?
Share your suggestions with us!