Bird
Raised Fist0
Expressframework~20 mins

Async middleware wrapper in Express - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Async Middleware Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What is the output of this async middleware wrapper?
Consider this Express async middleware wrapper function. What will be the response if the wrapped async function throws an error?
Express
const asyncWrapper = fn => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

app.get('/test', asyncWrapper(async (req, res) => {
  throw new Error('Oops');
}));
AThe server crashes with an unhandled promise rejection error.
BThe request hangs indefinitely with no response.
CThe client receives a 200 OK response with an empty body.
DThe error is passed to Express error handling middleware via next(), resulting in a 500 response.
Attempts:
2 left
💡 Hint
Think about how Promise.catch(next) works in Express middleware.
📝 Syntax
intermediate
2:00remaining
Which option correctly defines an async middleware wrapper in Express?
Select the option that correctly implements an async middleware wrapper function for Express.
Aconst asyncWrapper = fn => async (req, res, next) => { await fn(req, res, next).catch(next); };
Bconst asyncWrapper = fn => (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); };
Cconst asyncWrapper = fn => (req, res, next) => { try { fn(req, res, next); } catch (e) { next(e); } };
Dconst asyncWrapper = fn => (req, res, next) => { fn(req, res, next).catch(next); };
Attempts:
2 left
💡 Hint
Remember that async functions return promises and errors must be caught asynchronously.
🔧 Debug
advanced
2:00remaining
Why does this async middleware wrapper fail to catch errors?
Identify the problem in this async middleware wrapper code that causes errors thrown in the async function not to be caught.
Express
const asyncWrapper = fn => (req, res, next) => {
  try {
    fn(req, res, next);
  } catch (err) {
    next(err);
  }
};
AThe try/catch block does not catch errors from the async function because it returns a promise and errors happen asynchronously.
BThe next function is not called correctly inside the catch block.
CThe wrapper should use setTimeout to catch errors asynchronously.
DThe async function is not awaited, causing the wrapper to miss synchronous errors.
Attempts:
2 left
💡 Hint
Think about how errors in promises behave with try/catch.
❓ state_output
advanced
2:00remaining
What is the value of 'errorHandled' after this middleware runs?
Given this async middleware wrapper and route, what will be the value of the variable 'errorHandled' after a request triggers an error?
Express
let errorHandled = false;

const asyncWrapper = fn => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(err => {
    errorHandled = true;
    next(err);
  });
};

app.get('/fail', asyncWrapper(async (req, res) => {
  throw new Error('Fail');
}));

// Simulate a request to '/fail' and error handling middleware sets errorHandled to true
Atrue
Bfalse
Cundefined
Dnull
Attempts:
2 left
💡 Hint
The catch block sets errorHandled to true when an error occurs.
🧠 Conceptual
expert
3:00remaining
Which statement best explains why async middleware wrappers are important in Express?
Choose the best explanation for why wrapping async middleware functions with an error-catching wrapper is necessary in Express applications.
AAsync middleware wrappers improve performance by running middleware functions in parallel.
BWrapping async middleware automatically converts them into synchronous functions, simplifying error handling.
CExpress does not natively handle rejected promises in async middleware, so errors must be caught and passed to next() to avoid unhandled promise rejections and server crashes.
DAsync middleware wrappers are only needed when using Express with TypeScript.
Attempts:
2 left
💡 Hint
Consider how Express handles errors from promises by default.

Practice

(1/5)
1. What is the main purpose of using an async middleware wrapper in Express?
easy
A. To automatically catch errors from async route handlers without try-catch blocks
B. To convert synchronous middleware into asynchronous functions
C. To speed up the execution of middleware functions
D. To log all requests automatically

Solution

  1. Step 1: Understand async middleware challenges

    Async route handlers can throw errors that need to be caught to avoid crashing the app.
  2. Step 2: Role of async middleware wrapper

    The wrapper automatically catches errors from async functions and passes them to Express error handlers, avoiding manual try-catch blocks.
  3. Final Answer:

    To automatically catch errors from async route handlers without try-catch blocks -> Option A
  4. Quick Check:

    Async error catching = To automatically catch errors from async route handlers without try-catch blocks [OK]
Hint: Async wrapper catches errors, no manual try-catch needed [OK]
Common Mistakes:
  • Thinking it converts sync to async
  • Assuming it improves speed
  • Confusing it with logging middleware
2. Which of the following is the correct syntax to create an async middleware wrapper function in Express?
easy
A. const wrap = fn => (req, res, next) => { try { fn(req, res, next); } catch (err) { next(err); } };
B. const wrap = fn => (req, res, next) => fn(req, res, next).catch(next);
C. const wrap = fn => async (req, res, next) => { await fn(req, res, next); };
D. const wrap = fn => (req, res, next) => { fn(req, res, next).then(next); };

Solution

  1. Step 1: Understand async wrapper pattern

    The wrapper returns a function that calls the async function and catches errors with .catch(next).
  2. Step 2: Check each option

    const wrap = fn => (req, res, next) => { try { fn(req, res, next); } catch (err) { next(err); } }; uses try-catch but misses async/await and won't catch async errors properly. const wrap = fn => (req, res, next) => fn(req, res, next).catch(next); correctly returns a function that calls fn and catches errors with .catch(next). const wrap = fn => async (req, res, next) => { await fn(req, res, next); }; awaits but does not catch errors. const wrap = fn => (req, res, next) => { fn(req, res, next).then(next); }; calls then(next) which is incorrect for error handling.
  3. Final Answer:

    const wrap = fn => (req, res, next) => fn(req, res, next).catch(next); -> Option B
  4. Quick Check:

    Async wrapper uses .catch(next) = const wrap = fn => (req, res, next) => fn(req, res, next).catch(next); [OK]
Hint: Async wrapper uses .catch(next) to handle errors [OK]
Common Mistakes:
  • Using try-catch without async/await
  • Not returning the wrapped function
  • Misusing .then instead of .catch
3. Given the code below, what will be the output when a GET request is made to /data?
const express = require('express');
const app = express();

const wrap = fn => (req, res, next) => fn(req, res, next).catch(next);

app.get('/data', wrap(async (req, res) => {
  const data = await Promise.resolve('Hello World');
  res.send(data);
}));

app.use((err, req, res, next) => {
  res.status(500).send('Error caught');
});

app.listen(3000);
medium
A. Nothing, request hangs
B. Error caught
C. Hello World
D. SyntaxError

Solution

  1. Step 1: Analyze the async route handler

    The async function resolves 'Hello World' and sends it as response.
  2. Step 2: Check error handling

    No error occurs, so the error middleware is not triggered. The wrapper ensures errors would be caught if any.
  3. Final Answer:

    Hello World -> Option C
  4. Quick Check:

    Successful async response = Hello World [OK]
Hint: No error means normal response sent [OK]
Common Mistakes:
  • Assuming error middleware always runs
  • Thinking async wrapper changes output
  • Confusing promise resolution with error
4. Identify the error in the following async middleware wrapper code:
const wrap = fn => (req, res, next) => {
  try {
    fn(req, res, next);
  } catch (err) {
    next(err);
  }
};
medium
A. fn should not receive next as argument
B. Using try-catch inside middleware is not allowed
C. next(err) should be replaced with throw err
D. Missing async keyword and await, so async errors are not caught

Solution

  1. Step 1: Understand async error handling

    Async functions return promises; errors inside them are caught via .catch or await with try-catch.
  2. Step 2: Analyze the wrapper code

    The wrapper calls fn without await or .catch, so errors inside async fn are not caught by try-catch.
  3. Final Answer:

    Missing async keyword and await, so async errors are not caught -> Option D
  4. Quick Check:

    Async errors need await or .catch = Missing async keyword and await, so async errors are not caught [OK]
Hint: Try-catch alone misses async errors without await [OK]
Common Mistakes:
  • Thinking try-catch works without await
  • Confusing next(err) with throw
  • Believing next should not be passed
5. You want to create an async middleware wrapper that also logs the error message before passing it to Express error handler. Which of the following implementations correctly achieves this?
hard
A. const wrap = fn => (req, res, next) => fn(req, res, next).catch(err => { console.error(err.message); next(err); });
B. const wrap = fn => async (req, res, next) => { try { await fn(req, res, next); } catch (err) { next(err.message); } };
C. const wrap = fn => (req, res, next) => { fn(req, res, next).then(() => {}, err => { console.log(err); }); };
D. const wrap = fn => (req, res, next) => { try { fn(req, res, next); } catch (err) { console.error(err); next(err); } };

Solution

  1. Step 1: Understand error logging and forwarding

    We want to log the error message and then pass the full error to next() for Express to handle.
  2. Step 2: Evaluate each option

    const wrap = fn => (req, res, next) => fn(req, res, next).catch(err => { console.error(err.message); next(err); }); uses .catch to log err.message and calls next(err) correctly. const wrap = fn => async (req, res, next) => { try { await fn(req, res, next); } catch (err) { next(err.message); } }; passes err.message to next, which breaks error handling. const wrap = fn => (req, res, next) => { fn(req, res, next).then(() => {}, err => { console.log(err); }); }; logs error but does not call next, so error is not forwarded. const wrap = fn => (req, res, next) => { try { fn(req, res, next); } catch (err) { console.error(err); next(err); } }; uses try-catch without async/await, so async errors may be missed.
  3. Final Answer:

    const wrap = fn => (req, res, next) => fn(req, res, next).catch(err => { console.error(err.message); next(err); }); -> Option A
  4. Quick Check:

    Log then next(err) in .catch = const wrap = fn => (req, res, next) => fn(req, res, next).catch(err => { console.error(err.message); next(err); }); [OK]
Hint: Log error inside .catch, then call next(err) [OK]
Common Mistakes:
  • Passing err.message to next instead of err
  • Not forwarding error to next
  • Using try-catch without async/await
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard