- Synopsis
- Support
- Installation
- Error Flow
- Database Transaction Rollback
- Usage
- API Reference
- Logs
- Contributors
- Stack
Errandler-express.js is an open source Errandler gateway toolset for Express.js.
- πͺΆ Very lightweight
- β‘ High performance
- π§ Easy to use
- π¦ Only 1 dependency to log errors
- π§ͺ Thoroughly tested
- π Shipped as ECMAScript Express module
- π Written in TypeScript
- node: 22
This is the oldest targeted version.
$ npm i @dwtechs/errandler-expressβββββββββββββββββββ
β Error Occurs β
β next(error) β
βββββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββββββ
β Step 1: logError β
β β’ Log stack β
β β’ Log message β
β β’ next(err) ββββββΌβββ
ββββββββββββββββββββ β
β
βββββββββββββ
βΌ
βββββββββββββββββββββ
β Step 2: rollback β
β β’ Check db client β
β β’ ROLLBACK β
β β’ Release conn β
β β’ next(err) βββββββΌββ
βββββββββββββββββββββ β
β
βββββββββββββ
βΌ
βββββββββββββββββββββ
β Step 3: clientErr β
β β’ Get status β
β β’ Send response β
β β’ END CHAIN β
βββββββββββββββββββββ
ββββββββββββββββββββ
β No route matches β
β β’ Unmatched URL β
β β’ Send 404 β
ββββββββββββββββββββ
The error handling pipeline automatically manages database transaction rollback when errors occur, ensuring data consistency and preventing connexion leaks.
The rollbackTransaction middleware automatically detects a database client stored in res.locals.dbClient and performs rollback operations when errors occur:
- Detects Active Transaction: Checks for database client in
res.locals.dbClient - Executes ROLLBACK: Runs
ROLLBACKcommand to undo pending changes - Releases Connection: Returns connection to pool preventing memory leaks
- Cleans Up: Sets
res.locals.dbClienttoundefined
- Database client must be stored in
res.locals.dbClient - Client must have
query(sql)andrelease()methods - Transaction should be active (
BEGINalready executed)
// @ts-check
import express from "express";
// const cors = require("cors");
import { log } from '@dwtechs/winstan';
import { errorHandler } from "@dwtechs/errandler-express";
import { listen } from "@dwtechs/servpico-express";
const app = express();
app.disable("x-powered-by");
// Mandatory modules for any service
import health from "health";
// import services
// import middlewares
// import routes
app.use(express.json());
app.use("/health", health);
// Routes
app.use("/xx", ...);
app.use("/xxx", ...);
// Error handling
errorHandler(app);
// Init reference data
Promise.all([
data1.init(),
data2.init(),
])
.then(() => listen(app))
.catch((err) => log.error(`App cannot start: ${err.msg}`));import {
EC_CLIENT_BAD_REQUEST,
EC_CLIENT_UNAUTHORIZED,
EC_CLIENT_FORBIDDEN,
EC_CLIENT_NOT_FOUND,
EC_CLIENT_CONFLICT,
EC_CLIENT_MALFORMED_SYNTAX,
EC_CLIENT_TOO_MANY_REQUESTS,
EC_SERVER_INTERNAL_ERROR,
EC_SERVER_SERVICE_UNAVAILABLE
} from '@dwtechs/errandler-express';
// Create custom errors with status codes
function createValidationError(message: string) {
const error = new Error(message);
error.statusCode = EC_CLIENT_BAD_REQUEST;
return error;
}
// Use in middleware
app.use('/api/protected', (req, res, next) => {
if (!req.user) {
return res.status(EC_CLIENT_UNAUTHORIZED)
.send('Authentication required');
}
next();
});
// Error handling in routes
app.get('/api/users/:id', async (req, res, next) => {
try {
const user = await getUserById(req.params.id);
if (!user) {
return res.status(EC_CLIENT_NOT_FOUND)
.send('User not found');
}
res.json(user);
} catch (error) {
error.statusCode = EC_SERVER_INTERNAL_ERROR;
next(error);
}
});
/**
* Exported HTTP Error Status Codes grouped by category
* Client Error Responses (4xx)
* These errors indicate that the client made an error in the request
* Server Error Responses (5xx)
* These errors indicate that the server encountered an error
*/
const EC_CLIENT_BAD_REQUEST = 400; // 400 - The server cannot process the request due to client error
const EC_CLIENT_UNAUTHORIZED = 401; // 401 - Authentication is required and has failed or not been provided
const EC_CLIENT_FORBIDDEN = 403; // 403 - The client does not have access rights to the content
const EC_CLIENT_NOT_FOUND = 404; // 404 - The server cannot find the requested resource
const EC_CLIENT_CONFLICT = 409; // 409 - Request conflicts with the current state of the server
const EC_CLIENT_MALFORMED_SYNTAX = 422; // 422 - The request was well-formed but contains semantic errors
const EC_CLIENT_TOO_MANY_REQUESTS = 429; // 429 - The user has sent too many requests in a given time
const EC_SERVER_INTERNAL_ERROR = 500; // 500 - The server encountered an unexpected condition */
const EC_SERVER_SERVICE_UNAVAILABLE = 503; // 503 - The server is not ready to handle the request */
/**
* Sets up comprehensive error handling middleware for an Express application.
* This function configures a complete error handling pipeline that should be registered
* after all other middleware and routes to properly handle errors and invalid paths.
*
* The middleware stack is applied in the following order:
* 1. **Error Logging** - Logs error details for debugging and monitoring
* 2. **DB Transaction Rollback** - Rolls back database transactions on errors (PostgreSQL)
* 3. **Client Error Response** - Sends formatted HTTP error responses to clients
* 4. **Invalid Path Handling** - Handles 404 errors for undefined routes
*
* @param {Application} app - The Express application instance to configure with error handlers
*
* @returns {void} Configures the application with error handling middleware
*
* @example
* ```typescript
* import express from 'express';
* import { errorHandler } from './error';
*
* const app = express();
*
* // Configure your routes and middleware first
* app.use(express.json());
* app.get('/api/users', getUsersHandler);
* app.post('/api/users', createUserHandler);
*
* // Apply comprehensive error handling (should be last)
* errorHandler(app);
*
* app.listen(3000, () => {
* console.log('Server running with error handling configured');
* });
* ```
*
*/
function errorHandler(app) {}| Code | Value | Description |
|---|---|---|
EC_CLIENT_BAD_REQUEST |
400 | The server cannot process the request due to Client error |
EC_CLIENT_UNAUTHORIZED |
401 | Authentication is required and has failed or not been provided |
EC_CLIENT_FORBIDDEN |
403 | The Client does not have access rights to the content |
EC_CLIENT_NOT_FOUND |
404 | The server cannot find the requested resource |
EC_CLIENT_CONFLICT |
409 | Request conflicts with the current state of the server |
EC_CLIENT_MALFORMED_SYNTAX |
422 | The request was well-formed but contains semantic errors |
EC_CLIENT_TOO_MANY_REQUESTS |
429 | The user has sent too many requests in a given time |
EC_SERVER_INTERNAL_ERROR |
500 | The server encountered an unexpected condition |
EC_SERVER_SERVICE_UNAVAILABLE |
503 | The server is not ready to handle the request |
Errandler-express.js uses @dwtechs/Winstan library for logging. All logs are in debug mode. Meaning they should not appear in production mode.
Errandler-express.js is still in development and we would be glad to get all the help you can provide. To contribute please read contributor.md for detailed installation guide.
| Purpose | Choice | Motivation |
|---|---|---|
| repository | Github | hosting for software development version control using Git |
| package manager | npm | default node.js package manager |
| language | TypeScript | static type checking along with the latest ECMAScript features |
| module bundler | Rollup | advanced module bundler for ES6 modules |
| unit testing | Jest | delightful testing with a focus on simplicity |