express-error-bridge
v1.2.3
Published
Shared AppError class, error normalizer, and Express error-handling middleware that reports errors to a central error-tracking endpoint.
Maintainers
Readme
express-error-bridge
Shared AppError class, error normalizer, and Express error-handling middleware
that reports every caught error to a central error-tracking endpoint of your
choice — same middleware, same error shape, across as many services as you
want, each one just tagged with its own app name.
Install
npm install express-error-bridgeConfigure
The reporting client reads its target from environment variables, so the same code can point at a staging endpoint in staging and production in production without a code change:
| Env var | Required | Description |
|---|---|---|
| ADMIN_API_URL | yes | Base URL of your error-tracking service |
| ADMIN_API_KEY | yes | Shared key sent as the x-api-key header |
| ADMIN_ERROR_ENDPOINT_PATH | no | Path appended to ADMIN_API_URL, defaults to /api/errors |
If either required var is missing, reporting is silently skipped — it never throws and never blocks the response.
Usage
import express from 'express';
import { AppError, createErrorHandler, createNotFoundHandler } from 'express-error-bridge';
const app = express();
app.get('/companies/:id', async (req, res) => {
const company = await db.company.findUnique({ where: { id: req.params.id } });
if (!company) {
throw new AppError('Company not found', 404, 'NOT_FOUND');
}
res.json(company);
});
// mount last, after all routes
app.use(createNotFoundHandler());
app.use(createErrorHandler('my-service'));
app.listen(3000);Any error thrown (or passed to next(err)) inside a route handler flows to
createErrorHandler's middleware, which:
- Normalizes it into an
AppError(handles raw errors, Prisma, Mongoose, Axios, JWT, Zod, and Postgres constraint errors out of the box) - Logs it locally
- Fire-and-forgets a report to your
ADMIN_API_URLendpoint (never blocks or fails the response) — for 5xx errors specifically, the report also includes a sanitized snapshot of the request body/query (fields likepassword,token,secret,authorization, etc. are redacted by key name, and whole bodies on auth/credential paths are redacted outright). 4xx errors don't carry this — the message alone is usually enough for a validation failure, and it keeps routine noise down. - Sends the JSON response to the client
API
new AppError(message, statusCode = 500, code = 'INTERNAL_ERROR', details = null)
Throw this instead of a plain Error when you want control over the HTTP
status code and a stable, machine-readable code.
createErrorHandler(appName, options?)
Returns the Express error-handling middleware (err, req, res, next).
appName— identifies which service reported the error, e.g.'orders-api'options.logger— defaults toconsole; needs.warn/.erroroptions.extractContext(req)— pulls{ companyId, departmentId, userId }(or whatever tenant/user context matters to you) off the request; override when the default (req.user.companyId, etc.) doesn't match your auth shapeoptions.reporter— overrides for the reporting client (adminApiUrl,adminApiKey,timeoutMs)
createNotFoundHandler()
Returns a 404 handler that throws a NOT_FOUND AppError for any unmatched
route. Mount it right before createErrorHandler.
normalizeError(err)
Converts any thrown value into an AppError. Used internally by
createErrorHandler — call it directly only if you're building your own
error-handling middleware instead of using createErrorHandler.
reportError(payload, options?)
The reporting client itself. Called internally by createErrorHandler for
every request error. Call it directly for errors that happen outside
an Express request (cron jobs, queue consumers, startup failures) — nothing
else will report those automatically.
determineSeverity(statusCode, isOperational)
(statusCode, isOperational) => 'INFO' | 'WARNING' | 'ERROR' | 'CRITICAL'.
Used internally to tag each report.
captureRequestData(req)
(req) => { requestBody, queryParams }, sanitized. Used internally by
createErrorHandler for 5xx errors. Call it directly only if you're
building your own error-handling middleware and want the same redaction
behavior.
License
MIT
