Error handling in an asynchronous language works in a unique way and presents many challenges, some unexpected. There are seven main error handling patterns in Node.js. Let's briefly check them all.
Originally published on FullStack.Cafe - Never Fail Your Tech Interview Again
Error return value
Simplest pattern that doesn't work asynchronously. Consider:
var validateObject = function (obj) {
if (typeof obj !== 'object') {
return new Error('Invalid object');
}
};
Error throwing
Well-establish pattern, in which a function does its thing and if an error situation arises, it simply bails out throwing an error. Can leave you in an unstable state. It requires extra work to catch them. Also wrapping the async calls in try/catch won't help because the errors happen asynchronously. To fix this, we need domains. Domains provide an asynchronous try...catch.
var validateObject = function (obj) {
if (typeof obj !== 'object') {
throw new Error('Invalid object');
}
};
try {
validateObject('123');
}
catch (err) {
console.log('Thrown: ' + err.message);
}
Error callback
Returning an error via a callback is the most common error handling pattern in Node.js. Handling error callbacks can become a mess (callback hell or the pyramid of doom).
var validateObject = function (obj, callback) {
if (typeof obj !== 'object') {
return callback(new Error('Invalid object'));
}
return callback();
};
validateObject('123', function (err) {
console.log('Callback: ' + err.message);
});
Error emitting
When emitting errors, the errors are broadcast to any interested subscribers and handled within the same process tick, in the order subscribed.
var Events = require('events');
var emitter = new Events.EventEmitter();
var validateObject = function (a) {
if (typeof a !== 'object') {
emitter.emit('error', new Error('Invalid object'));
}
};
emitter.on('error', function (err) {
console.log('Emitted: ' + err.message);
});
validateObject('123');
Promises
Promises used for async error handling. Consider:
doWork()
.then(doWork)
.then(doError)
.then(doWork)
.catch(errorHandler)
.then(verify);
Try...catch with async/await
ES7 Async/await allows us as developers to write asynchronous JS code that look synchronous.
async function f() {
try {
let response = await fetch('http://no-such-url');
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
f();
Await-to-js lib
The variation on async/await without try-catch blocks in Javascript. Consider:
import to from 'await-to-js';
async function main(callback) {
const [err,quote] = await to(getQuote());
if(err || !quote) return callback(new Error('No Quote found');
callback(null,quote);
}
🔗Source: gist.github.com
Thanks 🙌 for reading and good luck on your interview!
Check more FullStack Interview Questions & Answers on 👉 www.fullstack.cafe
Top comments (1)
I took express.js to check how errors are handled. Here you can even test crash endpoints
dev.to/sandorturanszky/production-...