Creating Company-Standard Errors in Node.js Microservices (Part 1)
Introduction Error handling is crucial for any microservice architecture. A consistent error format helps in debugging, logging, and improving API responses. In this two-part series, we will explore how to set up company-standard errors using http-error-kit and @wthek/express-middleware. In Part 1, we will focus on global error formatting, ensuring that all errors in a microservice follow a unified structure. Part 2 will cover instance-level error formatting, allowing different error types to have unique formats. Why Standardized Errors Matter A standardized error format provides: Consistency - Every API follows the same structure, making integration easier for clients. Readability - Developers can quickly identify error details, reducing debugging time. Ease of Debugging - Log analysis and monitoring become easier, improving observability. Better AI & API Integration - Structured errors help AI models and API consumers handle failures better. Industry Perspectives on Error Standardization According to the JSON API Specification, using a structured format for errors helps maintain consistency across API responses (JSON API Specification - Errors). Leading API providers such as Google, Stripe, etc emphasize structured error responses as a key best practice for scalable and maintainable API ecosystems: Google Cloud API Design Guide suggests that error responses should follow a common structure to make client-side error handling easier (Google API Design Guide). Stripe API documentation enforces a strict format for errors to improve debugging and integration efficiency (Stripe API Errors). The Problem with Inconsistent Errors Imagine integrating with an API where every endpoint returns errors in a different format: GET /users → { "error": "User not found" } POST /orders → { "status": "error", "message": "Invalid order ID" } DELETE /products → { "code": 400, "msg": "Product cannot be deleted" } This inconsistency forces clients to write custom parsing logic for each API response, making integration painful. Instead, a unified error format ensures that clients handle errors consistently across all APIs. However, there are valid cases where different error types may need different structures. For example, validation errors might require field-specific details, while authentication errors may require retry hints. The key is to balance global consistency with error-type-specific flexibility, which we will achieve in Part 2. Step 1: Setting Up a Global Error Formatter The http-error-kit package allows us to define a global error structure that applies to all errors in our microservice. Let's define a company-standard format for errors. import { Config } from "http-error-kit"; Config.setGlobalFormatter((statusCode, message, details) => ({ errorCode: statusCode, errorMessage: message, errorDetails: details, timestamp: new Date().toISOString(), })); This formatter ensures that every error response in our microservice follows this structure: { "errorCode": 400, "errorMessage": "Invalid request", "errorDetails": { "field": "email" }, "timestamp": "2025-03-10T12:00:00.000Z" } Step 2: Integrating @wthek/express-middleware Once we have a global formatter, we need to ensure that Express automatically formats all error responses. This is where @wthek/express-middleware comes in. Installation First, install the required packages: npm install http-error-kit @wthek/express-middleware Applying Middleware to an Express Microservice Modify your Express server to use the middleware: import express from "express"; import { KitHttpError } from "http-error-kit"; import { KitExpressMiddleware } from "@wthek/express-middleware"; const app = express(); // Example Route app.get("/example", (req, res, next) => { next(new KitHttpError(400, "Invalid request", { field: "email" })); }); // Error Handling Middleware app.use(KitExpressMiddleware()); app.listen(3000, () => console.log("Server running on port 3000")); Now, when an error occurs, the response will follow our global formatter: { "errorCode": 400, "errorMessage": "Invalid request", "errorDetails": { "field": "email" }, "timestamp": "2025-03-10T12:00:00.000Z" } Summary By setting up a global error formatter and using @wthek/express-middleware, we have ensured that all errors in our microservice follow a standardized structure. However, not all errors should follow the exact same format. In many cases, different error types—such as validation errors, authentication errors, and database errors—need their own structure while maintaining consistency across APIs. What’s Next? In Part 2, we will explore how to extend http-error-kit to create custom error classes with different formats for specific error types. This allows us to achieve a balance between standardization and flexibilit

Introduction
Error handling is crucial for any microservice architecture. A consistent error format helps in debugging, logging, and improving API responses. In this two-part series, we will explore how to set up company-standard errors using http-error-kit and @wthek/express-middleware.
In Part 1, we will focus on global error formatting, ensuring that all errors in a microservice follow a unified structure. Part 2 will cover instance-level error formatting, allowing different error types to have unique formats.
Why Standardized Errors Matter
A standardized error format provides:
Consistency - Every API follows the same structure, making integration easier for clients.
Readability - Developers can quickly identify error details, reducing debugging time.
Ease of Debugging - Log analysis and monitoring become easier, improving observability.
Better AI & API Integration - Structured errors help AI models and API consumers handle failures better.
Industry Perspectives on Error Standardization
According to the JSON API Specification, using a structured format for errors helps maintain consistency across API responses (JSON API Specification - Errors). Leading API providers such as Google, Stripe, etc emphasize structured error responses as a key best practice for scalable and maintainable API ecosystems:
Google Cloud API Design Guide suggests that error responses should follow a common structure to make client-side error handling easier (Google API Design Guide).
Stripe API documentation enforces a strict format for errors to improve debugging and integration efficiency (Stripe API Errors).
The Problem with Inconsistent Errors
Imagine integrating with an API where every endpoint returns errors in a different format:
GET /users →
{ "error": "User not found" }
POST /orders →
{ "status": "error", "message": "Invalid order ID" }
DELETE /products →
{ "code": 400, "msg": "Product cannot be deleted" }
This inconsistency forces clients to write custom parsing logic for each API response, making integration painful. Instead, a unified error format ensures that clients handle errors consistently across all APIs.
However, there are valid cases where different error types may need different structures. For example, validation errors might require field-specific details, while authentication errors may require retry hints. The key is to balance global consistency with error-type-specific flexibility, which we will achieve in Part 2.
Step 1: Setting Up a Global Error Formatter
The http-error-kit
package allows us to define a global error structure that applies to all errors in our microservice. Let's define a company-standard format for errors.
import { Config } from "http-error-kit";
Config.setGlobalFormatter((statusCode, message, details) => ({
errorCode: statusCode,
errorMessage: message,
errorDetails: details,
timestamp: new Date().toISOString(),
}));
This formatter ensures that every error response in our microservice follows this structure:
{
"errorCode": 400,
"errorMessage": "Invalid request",
"errorDetails": { "field": "email" },
"timestamp": "2025-03-10T12:00:00.000Z"
}
Step 2: Integrating @wthek/express-middleware
Once we have a global formatter, we need to ensure that Express automatically formats all error responses. This is where @wthek/express-middleware comes in.
Installation
First, install the required packages:
npm install http-error-kit @wthek/express-middleware
Applying Middleware to an Express Microservice
Modify your Express server to use the middleware:
import express from "express";
import { KitHttpError } from "http-error-kit";
import { KitExpressMiddleware } from "@wthek/express-middleware";
const app = express();
// Example Route
app.get("/example", (req, res, next) => {
next(new KitHttpError(400, "Invalid request", { field: "email" }));
});
// Error Handling Middleware
app.use(KitExpressMiddleware());
app.listen(3000, () => console.log("Server running on port 3000"));
Now, when an error occurs, the response will follow our global formatter:
{
"errorCode": 400,
"errorMessage": "Invalid request",
"errorDetails": { "field": "email" },
"timestamp": "2025-03-10T12:00:00.000Z"
}
Summary
By setting up a global error formatter and using @wthek/express-middleware
, we have ensured that all errors in our microservice follow a standardized structure.
However, not all errors should follow the exact same format. In many cases, different error types—such as validation errors, authentication errors, and database errors—need their own structure while maintaining consistency across APIs.
What’s Next?
In Part 2, we will explore how to extend http-error-kit
to create custom error classes with different formats for specific error types. This allows us to achieve a balance between standardization and flexibility, ensuring different errors have different structures while keeping API-wide consistency.