Overview

Wrap async route handlers to catch errors. Eliminates try-catch boilerplate.

Features

  • Automatic error catching
  • Promise rejection handling
  • Clean route definitions
  • Zero dependencies

Installation

npx hanma add async-handler

Code

import { Request, Response, NextFunction, RequestHandler } from 'express';

/**
 * Type for async request handlers
 */
type AsyncRequestHandler = (
  req: Request,
  res: Response,
  next: NextFunction
) => Promise<unknown>;

/**
 * Wraps an async route handler to automatically catch and forward errors
 * Eliminates the need for try-catch blocks in every route
 * 
 * @example
 * // Instead of:
 * router.get('/users', async (req, res, next) => {
 *   try {
 *     const users = await User.findAll();
 *     res.json(users);
 *   } catch (err) {
 *     next(err);
 *   }
 * });
 * 
 * // You can write:
 * router.get('/users', asyncHandler(async (req, res) => {
 *   const users = await User.findAll();
 *   res.json(users);
 * }));
 */
export const asyncHandler = (fn: AsyncRequestHandler): RequestHandler => {
  return (req: Request, res: Response, next: NextFunction) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

/**
 * Alternative syntax using higher-order function
 * Can be used as a decorator-like pattern
 * 
 * @example
 * const getUsers = catchAsync(async (req, res) => {
 *   const users = await User.findAll();
 *   res.json(users);
 * });
 * 
 * router.get('/users', getUsers);
 */
export const catchAsync = asyncHandler; // Alias for those who prefer this name

/**
 * Wrap multiple handlers at once
 * 
 * @example
 * const [getUser, createUser, deleteUser] = wrapHandlers(
 *   async (req, res) => { ... },
 *   async (req, res) => { ... },
 *   async (req, res) => { ... },
 * );
 */
export const wrapHandlers = (
  ...handlers: AsyncRequestHandler[]
): RequestHandler[] => {
  return handlers.map(asyncHandler);
};

Usage

import { asyncHandler } from './middleware/utils/async-handler';

app.get('/users', asyncHandler(async (req, res) => {
  const users = await getUsers();
  res.json(users);
}));

Dependencies

No external dependencies required.

Frequently Asked Questions

How do I install Async Handler?
Run the following command: npx hanma add async-handler
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to middleware/utils/async-handler.ts.
Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.