Skip to content

Error Handling Project

DodaTech 2 min read

title: "API Error Handling Project — Build Robust Error Middleware" description: "Build a complete error handling system for an Express API with custom error classes, async wrappers, centralized middleware, structured responses, and logging." date: 2026-06-28 lastmod: 2026-06-28 weight: 30 tags: [apis, error-handling] }

Build a complete error handling system for a REST API including custom error classes, async error wrappers, centralized error middleware, structured responses, and logging.

What You'll Learn

  • Implementing a production-grade error handling system
  • Integrating error codes, trace IDs, and structured responses
  • Testing error handling middleware

Why It Matters

This project brings together all error handling concepts into a reusable system you can apply to any API.

Project Structure

error-handling-project/
  src/
    errors/
      AppError.js
      NotFoundError.js
      ValidationError.js
      AuthError.js
    middleware/
      errorHandler.js
      asyncHandler.js
      notFoundHandler.js
    routes/
      users.js
    app.js
  tests/
    errors.test.js

Error Classes

// errors/AppError.js
class AppError extends Error {
  constructor(message, statusCode = 400, code = null) {
    super(message);
    this.statusCode = statusCode;
    this.code = code || this.constructor.name;
    this.isOperational = true;
    Error.captureStackTrace(this, this.constructor);
  }

  toJSON() {
    return {
      error: this.code,
      message: this.message,
      status: this.statusCode
    };
  }
}

// errors/NotFoundError.js
class NotFoundError extends AppError {
  constructor(resource, id) {
    super(`${resource} '${id}' not found`, 404, 'NOT_FOUND');
    this.resource = resource;
    this.resourceId = id;
  }

  toJSON() {
    return {
      ...super.toJSON(),
      resource: this.resource,
      resource_id: this.resourceId
    };
  }
}

Middleware

// middleware/errorHandler.js
const { v4: uuidv4 } = require('uuid');

function errorHandler(err, req, res, next) {
  const traceId = uuidv4();
  const isOperational = err.isOperational || false;
  const statusCode = err.statusCode || 500;
  const code = err.code || 'INTERNAL_ERROR';

  console.error(`[${traceId}]`, {
    method: req.method,
    path: req.path,
    userId: req.user?.id,
    error: err.message,
    stack: err.stack
  });

  const response = {
    error: code,
    message: isOperational ? err.message : 'An unexpected error occurred',
    trace_id: traceId,
    ...(err.toJSON ? err.toJSON() : {})
  };

  res.status(statusCode).json(response);
}

module.exports = errorHandler;

Testing

// tests/errors.test.js
const request = require('supertest');
const app = require('../src/app');

describe('Error handling', () => {
  it('returns 404 for unknown routes', async () => {
    const res = await request(app).get('/unknown');
    expect(res.status).toBe(404);
    expect(res.body.error).toBe('NOT_FOUND');
  });

  it('returns structured 400 for validation errors', async () => {
    const res = await request(app)
      .post('/users')
      .send({});
    expect(res.status).toBe(400);
    expect(res.body.error).toBe('VALIDATION_ERROR');
    expect(res.body.fields).toBeDefined();
  });
});

Common Mistakes

1. Not Testing Error Cases

Integration tests should cover every error scenario.

2. Inconsistent Response Format

Test that all errors return the same JSON structure.

3. No Error Middleware in Production

Without proper middleware, unhandled errors crash the process.

4. Missing 404 Handler

The default 404 body is HTML, not JSON.

5. Not Handling Process-Level Errors

Add handlers for uncaught exceptions and unhandled rejections.

FAQ

Should I use a library or custom error handling?

: Custom gives you full control. Libraries like http-errors add convenience but limit flexibility.

How do I handle async errors in Express 4?

: Use the asyncHandler wrapper pattern shown above.

What is the best practice for error response format?

: RFC 7807 (Problem Details) is the standard for REST APIs.

What's Next

Your error handling knowledge is complete. Explore API Pagination or API Caching for more API design patterns.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro