Node.js Async Patterns & Error Handling 3 — Questions and Answers
Question 1: What does the `unhandledRejection` event on `process` allow you to do?
- Convert rejected promises to resolved ones
- Catch promise rejections that have no `.catch()` handler attached (Correct answer)
- Prevent Node.js from exiting on any error
- Restart the event loop after a crash
Correct answer: Catch promise rejections that have no `.catch()` handler attached
The `process.on('unhandledRejection', handler)` event fires when a Promise is rejected and no rejection handler is attached within the current event loop turn.
Question 2: What does `async function foo() { return 42; }` return when called?
- The number 42
- A Promise that resolves to 42 (Correct answer)
- A Promise that rejects with 42
- undefined
Correct answer: A Promise that resolves to 42
All async functions implicitly wrap their return value in `Promise.resolve()`, so calling an async function always returns a Promise.
Question 3: Which of the following correctly handles an error thrown inside a Promise executor?
- try/catch around new Promise()
- The Promise automatically rejects; attach a .catch() handler (Correct answer)
- process.on('uncaughtException')
- The error is silently swallowed
Correct answer: The Promise automatically rejects; attach a .catch() handler
Any exception thrown synchronously inside a Promise executor is automatically converted to a promise rejection.
Question 4: What is the difference between `Promise.race()` and `Promise.any()`?
- `Promise.race()` resolves/rejects with the first settled promise; `Promise.any()` resolves with the first fulfilled promise (Correct answer)
- `Promise.race()` only resolves; `Promise.any()` only rejects
- They are identical in behavior
- `Promise.any()` waits for all promises; `Promise.race()` does not
Correct answer: `Promise.race()` resolves/rejects with the first settled promise; `Promise.any()` resolves with the first fulfilled promise
`Promise.race()` settles (resolve or reject) as soon as the first promise settles, while `Promise.any()` ignores rejections and resolves with the first fulfillment.
Question 5: In Node.js streams, what event should you listen to for handling stream errors?
- 'fail'
- 'exception'
- 'error' (Correct answer)
- 'reject'
Correct answer: 'error'
All Node.js streams inherit from EventEmitter and emit an 'error' event when something goes wrong; unhandled stream errors crash the process.
Question 6: What is the purpose of the `finally()` method on a Promise?
- It converts a rejection to a resolution
- It runs a cleanup callback regardless of whether the promise fulfilled or rejected (Correct answer)
- It cancels the promise if it takes too long
- It prevents the promise chain from propagating errors
Correct answer: It runs a cleanup callback regardless of whether the promise fulfilled or rejected
`Promise.prototype.finally()` executes its callback when the promise settles (either way) without changing the resolved value or rejection reason.
Question 7: How do you implement a timeout for a Promise-based operation in Node.js?
- Pass a timeout option to the Promise constructor
- Use Promise.race() with a rejecting setTimeout promise (Correct answer)
- Use process.nextTick() with a counter
- Wrap the promise in setInterval()
Correct answer: Use Promise.race() with a rejecting setTimeout promise
`Promise.race()` between your operation and a `new Promise((_, reject) => setTimeout(reject, ms))` pattern implements a timeout.
What does the `unhandledRejection` event on `process` allow you to do?