Lesson 32 +10 XP

Async Error Wrapping (express-async-handler)

Synchronous errors inside route handlers are automatically caught by Express. However, unhandled promise rejections inside async route functions will hang the request unless explicitly caught or wrapped!

Manual try/catch Approach


javascript
app.get("/users/:id", async (req, res, next) => {
  try {
    const user = await User.findById(req.params.id);
    if (!user) throw new Error("User not found");
    res.json(user);
  } catch (err) {
    next(err); // Must call next(err) manually!
  }
});

Cleaner Solution: Higher-Order Async Wrapper

Avoid repeating try/catch in dozens of routes by wrapping async route handlers:


javascript
// Higher-order function wrapper
const asyncHandler = (fn) => (req, res, next) => {

### Promise.resolve(fn(req, res, next)).catch(next);
};

// Usage with asyncHandler (No try/catch block needed!)
app.get("/users/:id", asyncHandler(async (req, res) => {
  const user = await User.findById(req.params.id);
  if (!user) {
    const error = new Error("User not found");
    error.statusCode = 404;
    throw error;
  }
  res.json(user);
}));

TL;DR

  • Async routes throw unhandled rejections if errors are not caught.
  • Use an asyncHandler utility or the express-async-errors package to eliminate repetitive try/catch blocks.