Async Handler

The Async Handler component is a foundational Express utility that ensures all errors thrown inside asynchronous route handlers are reliably captured and forwarded to Express’s global error middleware.

It eliminates repetitive try/catch blocks and ensures all rejected promises are properly forwarded to Express’s centralized error-handling middleware.

  • Eliminates try/catch boilerplate,
  • Full TypeScript support,
  • Seamless Express integration,
  • Minimal performance overhead,
  • Works with any error handler

This component is designed to be:

  • Minimal
  • Framework-native
  • Fully type-safe
  • Compatible with any Express error handler

Installation Guide

Install the component using the ServerCN CLI:

npx servercn add async-handler

The Core Problem in Express

Express was originally designed around synchronous middleware. Express.js doesn't automatically catch errors from async functions

Async Handler wraps async routes and properly forwards all errors.

As a result:

  • Errors thrown synchronously are caught automatically
  • Errors thrown inside async functions are not
router.get("/users", async (_req, res) => {
  throw new Error("Database unavailable");
});

Basic Implementation

src/utils/async-handler.ts
import { Request, Response, NextFunction } from "express";
 
export type AsyncRouteHandler = (
  req: Request,
  res: Response,
  next: NextFunction
) => Promise<unknown>;
 
export function AsyncHandler(fn: AsyncRouteHandler) {
  return function (req: Request, res: Response, next: NextFunction) {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
}
src/shared/utils/async-handler.ts
import { Request, Response, NextFunction } from "express";
 
export type AsyncRouteHandler = (
  req: Request,
  res: Response,
  next: NextFunction
) => Promise<unknown>;
 
export function AsyncHandler(fn: AsyncRouteHandler) {
  return function (req: Request, res: Response, next: NextFunction) {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
}

Usage Example


import { Request, Response, NextFunction } from "express";
import { AsyncHandler } from "..utils/async-handler";
 
export const registerUser = AsyncHandler(async (req: Request, res: Response, next: NextFunction) => {
  /*
   * business logic
   * your actual code
   */
});

File & Folder Structure

Select a file to view its contents

Installation

npx servercn add async-handler