Consider this Express route handler using async/await:
app.get('/data', async (req, res) => {
const data = await fetchData();
if (!data) throw new Error('No data found');
res.json(data);
});What will Express do if fetchData() returns null causing the error to be thrown?
Think about how Express handles errors in async functions without calling next().
Express does not automatically catch errors thrown inside async route handlers unless the error is passed to next(). Without error handling middleware or calling next(error), the request hangs.
Given an async route, which code snippet correctly forwards errors to Express's error middleware?
Look for the option that uses next(err) inside a try/catch block.
Option A correctly catches errors in async code and passes them to Express's error handler by calling next(err). Option A uses promises but is not async/await. Option A handles error but sends response directly, bypassing error middleware. Option A throws error without catching.
Examine this Express route:
app.get('/items', async (req, res, next) => {
fetchItems().then(items => {
if (!items) throw new Error('No items');
res.json(items);
});
});Why won't errors thrown inside then() be caught by Express's error handler?
Consider how async functions and promises interact with error propagation.
The async function returns immediately without awaiting fetchItems(). Errors inside the then() callback are not caught by Express because the promise chain is not awaited or handled with catch(next).
Why do many Express apps use a wrapper like const wrap = fn => (req, res, next) => fn(req, res, next).catch(next); around async route handlers?
Think about how error handling is simplified with this pattern.
The wrapper catches any rejected promise from the async function and calls next(error), so you don't need try/catch in every route handler.
Given this Express setup:
app.get('/fail', async (req, res, next) => {
try {
await Promise.reject(new Error('Failed'));
} catch (err) {
next(err);
}
});
app.use((err, req, res, next) => {
res.status(400).json({ error: err.message });
});What will the client receive when requesting /fail?
Look at the error middleware and the status code it sets.
The error middleware sets status 400 and sends JSON with the error message. Calling next(err) triggers this middleware.