StatusFlow provides two Express middleware functions for handling errors and responses in your application.
httpErrorMiddleware
Express error middleware for handling HttpException instances and converting them to JSON responses.
Function Signature
function httpErrorMiddleware(
err: unknown,
req: Request,
res: Response,
_next: NextFunction
): void
Parameters
The error object. Can be an HttpException instance or any other error type.
The Express request object.
The Express response object.
The Express next function (not used in this middleware).
Behavior
-
If error is HttpException: Converts the exception to a structured HTTP response using
createHttpResponse() and sends it with the appropriate status code.
-
If error is not HttpException: Sends a generic 500 Internal Server Error response with the error details.
For HttpException:
{
"status": 404,
"message": "User not found",
"details": { "userId": "12345" }
}
For other errors:
{
"status": 500,
"message": "Internal Server Error",
"details": "<error object>"
}
Example Usage
import express from 'express';
import { httpErrorMiddleware, NotFoundException } from 'status-flow';
const app = express();
// Your routes
app.get('/users/:id', async (req, res, next) => {
try {
const user = await userService.findById(req.params.id);
if (!user) {
throw new NotFoundException('User not found', {
userId: req.params.id
});
}
res.json({ success: true, data: user });
} catch (error) {
next(error);
}
});
// Error middleware (must be registered AFTER routes)
app.use(httpErrorMiddleware);
app.listen(3000);
statusFlowMiddleware
Express error middleware that uses the StatusFlow function to generate bilingual responses based on error codes.
Function Signature
function statusFlowMiddleware(
err: any,
req: Request,
res: Response,
_next: NextFunction
): void
Parameters
The error object. Expected to have a code property with the HTTP status code.
The Express request object. The middleware reads the x-lang header to determine the response language.
The Express response object.
The Express next function (not used in this middleware).
Behavior
-
Language Detection: Checks the
x-lang header in the request:
- If
x-lang: en, uses English
- Otherwise, defaults to Spanish
-
Error with valid code: If the error has a numeric
code property, uses StatusFlow to generate a response with:
- The error code
- Detected language
- Custom message from
err.message (if present)
- Extra data from
err.extra (if present)
-
Error without valid code: Falls back to a 500 Internal Server Error response in Spanish.
{
"success": false,
"message": "HTTP 404 - Not Found",
"code": 404,
"info": {
"name": "Not Found",
"category": "Client Error",
"description": "Standard HTTP client error code 404.",
"possibleCauses": ["General cause depending on context."]
}
}
Example Usage
import express from 'express';
import { statusFlowMiddleware } from 'status-flow';
const app = express();
app.get('/users/:id', async (req, res, next) => {
try {
const user = await userService.findById(req.params.id);
if (!user) {
// Create error with code property
const error = new Error('User not found');
(error as any).code = 404;
(error as any).extra = { userId: req.params.id };
throw error;
}
res.json({ success: true, data: user });
} catch (error) {
next(error);
}
});
// Register StatusFlow middleware
app.use(statusFlowMiddleware);
app.listen(3000);
# English response
curl -H "x-lang: en" http://localhost:3000/users/999
# Spanish response (default)
curl http://localhost:3000/users/999
Custom Error Factory
class StatusFlowError extends Error {
constructor(
public code: number,
message?: string,
public extra?: Record<string, any>
) {
super(message);
}
}
app.get('/api/resource', (req, res, next) => {
try {
if (!authorized) {
throw new StatusFlowError(403, 'Access denied', {
requiredRole: 'admin'
});
}
} catch (error) {
next(error);
}
});
Middleware Comparison
| Feature | httpErrorMiddleware | statusFlowMiddleware |
|---|
| Input | HttpException classes | Errors with code property |
| Response Format | Simple HTTP response | Full StatusFlow response |
| Bilingual Support | No | Yes (via x-lang header) |
| Metadata | Basic | Full status info |
| Use Case | Simple REST APIs | Bilingual applications |
Combining Both Middlewares
You can use both middlewares together by registering them in sequence:
import express from 'express';
import {
httpErrorMiddleware,
statusFlowMiddleware,
HttpException
} from 'status-flow';
const app = express();
// Routes...
// First, handle HttpException instances
app.use((err: any, req: any, res: any, next: any) => {
if (err instanceof HttpException) {
return httpErrorMiddleware(err, req, res, next);
}
next(err);
});
// Then, handle errors with code property
app.use(statusFlowMiddleware);
Best Practices
1. Register Error Middleware Last
Error middleware must be registered after all routes:
// ✅ Correct
app.get('/users', handler);
app.post('/users', handler);
app.use(httpErrorMiddleware); // After routes
// ❌ Incorrect
app.use(httpErrorMiddleware); // Before routes
app.get('/users', handler);
2. Always Call next(error)
In async route handlers, always pass errors to next():
app.get('/users/:id', async (req, res, next) => {
try {
const user = await findUser(req.params.id);
res.json(user);
} catch (error) {
next(error); // Pass to error middleware
}
});
3. Use Appropriate Exception Classes
Choose the right exception class for the error type:
// User input errors
throw new BadRequestException('Invalid email');
// Authentication errors
throw new UnauthorizedException('Token expired');
// Authorization errors
throw new ForbiddenException('Admin only');
// Not found errors
throw new NotFoundException('User not found');
// Resource conflicts
throw new ConflictException('Email already exists');
4. Include Helpful Details
Provide additional context in the details field:
throw new BadRequestException('Validation failed', {
fields: {
email: 'Invalid format',
age: 'Must be positive'
}
});
TypeScript Support
Both middleware functions are fully typed:
import { Request, Response, NextFunction } from 'express';
import { httpErrorMiddleware } from 'status-flow';
// Type-safe usage
const errorHandler: (
err: unknown,
req: Request,
res: Response,
next: NextFunction
) => void = httpErrorMiddleware;