Skip to main content
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

err
unknown
required
The error object. Can be an HttpException instance or any other error type.
req
Request
required
The Express request object.
res
Response
required
The Express response object.
_next
NextFunction
required
The Express next function (not used in this middleware).

Behavior

  1. If error is HttpException: Converts the exception to a structured HTTP response using createHttpResponse() and sends it with the appropriate status code.
  2. If error is not HttpException: Sends a generic 500 Internal Server Error response with the error details.

Response Format

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

err
any
required
The error object. Expected to have a code property with the HTTP status code.
req
Request
required
The Express request object. The middleware reads the x-lang header to determine the response language.
res
Response
required
The Express response object.
_next
NextFunction
required
The Express next function (not used in this middleware).

Behavior

  1. Language Detection: Checks the x-lang header in the request:
    • If x-lang: en, uses English
    • Otherwise, defaults to Spanish
  2. 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)
  3. Error without valid code: Falls back to a 500 Internal Server Error response in Spanish.

Response Format

{
  "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);

With Language Header

# 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

FeaturehttpErrorMiddlewarestatusFlowMiddleware
InputHttpException classesErrors with code property
Response FormatSimple HTTP responseFull StatusFlow response
Bilingual SupportNoYes (via x-lang header)
MetadataBasicFull status info
Use CaseSimple REST APIsBilingual 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;

Build docs developers (and LLMs) love