0
0
ExpressDebug / FixBeginner · 4 min read

How to Handle Async Routes in Express Correctly

In Express, async route handlers must catch errors explicitly or use middleware like express-async-errors to avoid unhandled promise rejections. Wrap your async functions with try/catch blocks or pass errors to next() to handle them properly.
🔍

Why This Happens

Express does not automatically catch errors thrown inside async route handlers. If you write an async function without error handling, any error will cause the server to hang or crash because Express doesn't know how to handle the rejected promise.

javascript
const express = require('express');
const app = express();

app.get('/data', async (req, res) => {
  // Simulate an error
  const data = await Promise.reject(new Error('Failed to fetch data'));
  res.send(data);
});

app.listen(3000);
Output
UnhandledPromiseRejectionWarning: Error: Failed to fetch data (node:...) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
🔧

The Fix

Wrap your async code in a try/catch block and pass errors to next(). This lets Express handle errors with its error middleware. Alternatively, use the express-async-errors package to automatically catch async errors.

javascript
const express = require('express');
const app = express();

app.get('/data', async (req, res, next) => {
  try {
    const data = await Promise.reject(new Error('Failed to fetch data'));
    res.send(data);
  } catch (err) {
    next(err); // Pass error to Express error handler
  }
});

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send({ error: err.message });
});

app.listen(3000);
Output
{"error":"Failed to fetch data"}
🛡️

Prevention

Always handle errors in async routes using try/catch or use middleware like express-async-errors to avoid repeating error handling code. Use linting rules to warn about unhandled promises and test routes to ensure errors are caught.

Example best practices:

  • Wrap async route logic in try/catch.
  • Use centralized error middleware.
  • Consider express-async-errors for cleaner code.
  • Test error cases during development.
⚠️

Related Errors

Similar issues include unhandled promise rejections in middleware or event handlers. These can be fixed by consistent error handling and using next(err) or global error handlers. Another common error is forgetting to add next as a parameter in async routes, which prevents error forwarding.

Key Takeaways

Always use try/catch in async Express routes to handle errors.
Pass errors to next() to let Express handle them properly.
Use express-async-errors package to simplify async error handling.
Add error-handling middleware to catch and respond to errors.
Test your routes for error cases to prevent server crashes.