There is a plethora of questions on Stack Overflow about NodeJS best practices when it comes to error handling best practices, specifically regarding operational errors. After an entire morning of reading articles and watching talks about best practices, I'm more confused than ever.
Here's a snippet from logic to register a new user with my service:
const registerUser = new Promise((resolve, reject) => {
bcrypt.genSalt(10, (err, salt) => {
if (err) {
reject(new Error('An error occurred while generating password salt.'));
} else {
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) {
reject(new Error('An error occurred while hashing password.'));
} else {
user.password = hash;
user.save().then((err, user) => {
if(err) {
reject(new Error('An error occurred while saving the user.'));
}
resolve(user);
});
}
});
}
});
}
I'm leveraging callbacks, where the first argument is an Error object. This aligns with the NodeJS docs on error first callbacks: https://nodejs.org/api/errors.html#errors_error_first_callbacks.
But the community seems to maintain that callbacks suck and lead to temples of doom like the code above. For example, there is a NodeJS best practices repo on GitHub with 19,120 stars. On the main page, contributors state:
Node.js callback style, function(err, response), is a promising way to un-maintainable code due to the mix of error handling with casual code, excessive nesting and awkward coding patterns
Source: https://github.com/i0natan/nodebestpractices#2-error-handling-practices
What gives? What's the best way to handle everyday operational errors in a NodeJS application? Are the NodeJS docs promoting anti-patterns? This seems like a simple thing that should be standardized, yet after hours of searching, I cannot find a single source of truth or accepted standard.