Usage
Usage ds-express-errors is straightforward. Start by importing the necessary handlers and initializing them at the root of your application, after all your routes have been defined. This ensures that all errors are caught and processed correctly by the middleware.
1. Throwing Errors (Presets)
The library provides a set of pre-configured error classes (Presets) mapped to standard HTTP status codes. You don't need to manually manage status codes.
import { Errors } from 'ds-express-errors';
app.get('/users/:id', async (req, res, next) => {
const user = await getUserById(req.params.id);
if (!user) {
// Throws 404 Not Found
return next(Errors.NotFound('User with this ID does not exist'));
}
if (!user.hasAccess) {
// Throws 403 Forbidden
return next(Errors.Forbidden('Access denied'));
}
res.json(user);
});2. Async Handler
Wrap your async route handlers with asyncHandler to automatically catch rejected promises. This eliminates the need for try-catch blocks in every controller.
import { asyncHandler, Errors } from 'ds-express-errors';
const createUser = asyncHandler(async (req, res) => {
// If db.create fails, the error is automatically passed to next()
const newUser = await db.create(req.body);
if (!newUser) throw Errors.BadRequest('Invalid data');
res.status(201).json(newUser);
});
app.post('/users', createUser);3. Automatic Error Mapping
ds-express-errors automatically detects and maps 3rd-party library errors to readable HTTP responses. No extra configuration required.
Supported libraries:
- Validation:
Zod,Joi→400 Bad Request;express-validator→400 Bad Requestor422 Unprocessable Content(with formatted issues) - Database (ORM):
Prisma(ClientKnownRequest),Mongoose(DuplicateKey, CastError, ValidationError),Sequelize→400 Bad Request - Auth:
jsonwebtoken(Expired, Invalid) →401 Unauthorized
If the library encounters an error for which no explicit mapping is defined (e.g., a new or rare system error), it will not “drop” the process.
Any unrecognized error will be safely converted to a standard: 500 Internal Server Error, and its details will be automatically recorded in the server logs. This ensures that the client always receives a clean, standardized JSON response and the application remains stable.
Example Zod: If a Zod validation fails, the client receives:
Important
url, stack, method are available in development mode, if you want to change that setting, you can redefine them by setConfig
{
"status": "fail",
"method": "GET",
"url": "/login",
"message": "Validation error: email: Invalid email",
"stack": ...
}4. Handling 404 (Not Found)
Express does not handle 404 errors as exceptions by default. To catch requests to non-existent routes and return a JSON response, add a catch-all handler before the errorHandler.
import { Errors, errorHandler } from 'ds-express-errors';
// ... your routes ...
app.get('/users', getUsers);
// 1. Catch 404 and forward to error handler
app.use('*', (req, res, next) => {
next(Errors.NotFound("Route " + req.originalUrl + " not found"));
});
// 2. Global Error Handler
app.use(errorHandler);Custom Logger (v1.4.0+)
By default, ds-express-errors prints logs to the console. However, in production, you might want to send logs to a file or an external service using libraries like Winston or Pino.
You can pass your logger instance to setConfig. The logger object must satisfy the Logger interface (implement error, warn, info, debug methods).
// Example with Winston
import winston from 'winston'
const { setConfig } = require('ds-express-errors');
const logger = winston.createLogger({ /* options */ });
setConfig({ customLogger: logger });