Skip to main content

Error Handling with Promises

Promises/Async/Await: Error / Promises



How does error handling work with JavaScript promises?

View Answer:
Interview Response: Promises in JavaScript provide a .catch() method to handle errors. If a promise is rejected, the associated .catch() block is executed, allowing for error handling and recovery.

Code Example:

function fetchUserData() {
return new Promise((resolve, reject) => {
// Simulating an asynchronous operation
setTimeout(() => {
const user = { id: 1, name: 'John Doe' };

// Simulating an error condition
if (!user) {
reject('Failed to fetch user data.');
} else {
resolve(user);
}
}, 2000);
});
}

fetchUserData()
.then(user => {
console.log('User data:', user);
})
.catch(error => {
console.error('Error:', error);
});


What is an implicit try…catch in relation to promises in JavaScript?

View Answer:
Interview Response: An implicit try-catch in Promises refers to the automatic error capturing by Promises, wrapping the code inside "then" or "catch" callbacks, making it unnecessary to use explicit try-catch blocks.

Technical Response: The code of a promise executor and promise handlers have an "invisible try..catch" around it. If an exception happens, it gets caught and treated as a rejection. This outcome happens not only in the executor function but also in its handlers. If we throw inside a .then handler, that means a rejected promise, so the control jumps to the nearest error handler. This outcome happens for all errors, not just those caused by the throw statement, including programming errors.

Code Example:

new Promise((resolve, reject) => {
throw new Error('Whoops!');
}).catch(console.log); // Error: Whoops!

// Works exactly the same as this:

new Promise((resolve, reject) => {
reject(new Error('Whoops!'));
}).catch(console.log); // Error: Whoops!

// Example in dot then
new Promise((resolve, reject) => {
resolve('ok');
})
.then((result) => {
throw new Error('Whoops!'); // rejects the promise
})
.catch(console.log); // Error: Whoops!

In a regular try...catch, we can analyze the error and maybe rethrow it if we can't handle it. Is the same thing possible for promises?

View Answer:
Interview Response: Yes, the same thing is possible for promises. If we throw inside .catch, the control goes to the next closest error handler, and if we handle the error and finish usually, it continues to the next closest successful Promise.then() handler.

Code Example:

// the execution: catch -> then
new Promise((resolve, reject) => {
throw new Error('Whoops!');
})
.catch(function (error) {
console.log('The error is handled, continue normally');
})
.then(() => console.log('Next successful handler runs'));

What happens when an error is unhandled in a promise?

View Answer:
Interview Response: When an error is unhandled in a Promise, it results in an unhandled Promise rejection. Modern JavaScript environments, like Node.js and browsers, emit a warning or event for unhandled rejections.

Technical Response: In practice, something has gone wrong, just like with regular unhandled code errors. The script terminates with an error message on the console. Unhandled promise rejections behave similarly, and the JavaScript engine monitors such rejections and emits a global error in such cases. We may catch such errors in the browser by utilizing the event `unhandledrejection`.

Code Example:

window.addEventListener('unhandledrejection', function (event) {
// the event object has two special properties:
console.log(event.promise); // [object Promise] - the promise that generated the error
console.log(event.reason); // Error: Whoops! - the unhandled error object
});

new Promise(function () {
throw new Error('Whoops!');
}); // no catch to handle the error

What happens to unhandled promise rejections?

View Answer:
Interview Response: Unhandled promise rejections generate a warning in most environments and may be treated as uncaught exceptions, potentially causing memory leaks or unexpected application behavior if not properly addressed.

How can you catch multiple errors with a single catch() method?

View Answer:
Interview Response: A single catch() method in a promise chain will handle any errors from preceding promises, allowing centralized error handling and reducing the need for multiple error handlers in the chain.

How can you handle different errors in a promise chain?

View Answer:
Interview Response: To handle different errors in a promise chain, place catch() methods after each then() method, allowing you to specifically handle errors related to each individual asynchronous operation or use conditional statements within a single catch().

Can you recover from an error in a promise chain?

View Answer:
Interview Response: Yes, you can recover from an error in a promise chain by returning a new promise or value from within a catch() method, allowing the chain to continue or perform a different action based on the error.

How do you handle errors that occur in a catch() method?

View Answer:
Interview Response: To handle errors that occur in a catch() method, attach another catch() method after the first one, which will handle any errors thrown or unhandled rejections from the preceding catch() callback.

What is the role of the finally() method in error handling with promises?

View Answer:
Interview Response: The finally() method in promises executes regardless of the promise's outcome, allowing you to run cleanup or follow-up code after both successful resolution and error rejection, without impacting error handling.

How can you handle timeouts or retries in error handling with promises?

View Answer:
Interview Response: To handle timeouts or retries with promises, use Promise.race() or custom logic within a promise executor function to reject or resolve based on time elapsed, then handle the resulting error or retry within a catch() method.

How do promises improve error handling compared to callbacks?

View Answer:
Interview Response: Promises improve error handling compared to callbacks by providing a cleaner, more maintainable structure through chaining, centralized error handling with catch(), and better propagation of errors across asynchronous operations.

Can you use async/await to handle errors with promises?

View Answer:
Interview Response: Yes, async/await can be used for error handling with promises by using try-catch blocks within async functions, allowing you to handle promise rejections in a synchronous-like manner, improving code readability and structure.