DEV Community

Cover image for Standardizing Express.js Error Handling with One Library
Diana
Diana

Posted on

Standardizing Express.js Error Handling with One Library

If you've been working with Express.js for a while, you know the struggle. You start a project, and soon your controllers look like this:

// The "Bad" Way
app.post('/users', async (req, res) => {
  try {
    // ... logic
  } catch (error) {
    console.error(error);
    if (error.code === 'P2002') { // Prisma unique constraint
        return res.status(400).json({ message: 'User already exists' });
    }
    // ... 10 more if/else checks
    res.status(500).json({ message: 'Something went wrong' });
  }
});
Enter fullscreen mode Exit fullscreen mode

It's repetitive, hard to maintain, and prone to bugs. I got tired of copy-pasting error handling logic between my projects, so I built a tool to fix it once and for all.

​Meet ds-express-errors.

What is it?

ds-express-errors is a centralized, type-safe error handling library for Node.js & Express. It aims to replace all your manual try-catch blocks and status code management with a clean, declarative API.
​Here is why I think it's worth checking out:

Ready-to-use Presets 🛠️

​Forget about remembering if "Forbidden" is 401 or 403. Just use the presets.

import { Errors } from 'ds-express-errors';

if (!user) {
  throw Errors.NotFound('User not found'); // Automatically sends 404
}

if (!user.hasAccess) {
  throw Errors.Forbidden('Access denied'); // Automatically sends 403
}
Enter fullscreen mode Exit fullscreen mode

Auto-Mapping (The Magic 🪄)

​This is my favorite part. If you use Zod, Prisma, or Mongoose, the library automatically detects their native errors and converts them into readable HTTP 400 Bad Requests.

Example with Zod:
You don't need to manually parse error.issues.

Input (Invalid):

{ "email": "invalid-email" }
Enter fullscreen mode Exit fullscreen mode

Output (Automatic):

{
  "status": "fail",
  "method": "GET",
  "url": "/login",
  "message": "Validation error: email: Invalid email",
  "stack": // showed when NODE_ENV=development
}
Enter fullscreen mode Exit fullscreen mode

No More try/catch


With the included asyncHandler, your controllers become clean again.

import { asyncHandler, Errors } from 'ds-express-errors';

const createUser = asyncHandler(async (req, res) => {
  const user = await db.create(req.body); // If this throws, it's handled automatically!
  res.json(user);
});
Enter fullscreen mode Exit fullscreen mode

Graceful Shutdown 🛑

​It also handles process-level errors (uncaughtException, unhandledRejection) and allows you to close database connections gracefully before crashing.

import { initGlobalHandlers } from 'ds-express-errors';

initGlobalHandlers({
  onCrash: () => {
    db.disconnect();
    server.close();
  }
});
Enter fullscreen mode Exit fullscreen mode

Configuration (Custom Response Format)

You can customize the structure of the error response sent to the client. This is useful if you need to adhere to a specific API standard (e.g., JSON:API) or hide certain fields.

Use setConfig before initializing the error handler middleware.

const { setConfig, errorHandler } = require('ds-express-errors');

// Optional: Customize response format
setConfig({
    formatError: (err, req, isDev) => {
        return {
            success: false,
            error: {
                code: err.statusCode,
                message: err.message,
                // Add stack trace only in development
                ...(isDev ? { debug_stack: err.stack } : {})
            }
        };
    }
});
const app = express();
// ... your routes ...
app.use(errorHandler);
Enter fullscreen mode Exit fullscreen mode

Default Format
If no config is provided, the library uses the default format:

{
  "status": "error", // or 'fail'
  "method": "GET",
  "url": "/api/resource",
  "message": "Error description",
  "stack": // showed when NODE_ENV=development
}
Enter fullscreen mode Exit fullscreen mode

📦 How to use it?

​Installation is standard:

npm install ds-express-errors
Enter fullscreen mode Exit fullscreen mode

📚 Documentation


I've built a full documentation website where you can see advanced usage, API references, and more examples:

👉ds-express-errors.dev

Conclusion

​Building this library helped me standardize my backend projects, and I hope it helps you too. It's fully typed (TypeScript), lightweight, and production-ready.

Give it a try and let me know what you think! Any feedback or stars on a GitHub are highly appreciated. ❤️

Top comments (0)