In Node.js, error handling is crucial in the building of stable and scalable applications. A good error-handling scheme lets the application gracefully handle unexpected situations, minimize downtime, and provide a better customer experience. In this blog, we will review the various error-handling techniques.
Why Is Error Handling Important?
Error handling is most certainly not limited to catching and logging errors; this system assures:
- Stability for the application.
- Eased in the process of debugging and troubleshooting.
- Safeguarded performance to avoid any leakage of information.
- Earned meaningful feedback from users.
Types of Errors in Node.js
Broadly speaking, there are three types of errors found within the realm of Node.js:
System errors
They arise from the operating system or the environment causing a problem (e.g. file not found, network unavailable).
Operational errors
These are predictable and can be due to wrong user input or any application-specific problems.
Programmer errors
These are mistakes in coding or logical issues made from within the code.
Key Techniques for Handling Errors in NodeJS
Using try-catch block
The try-catch block can be used to handle errors thrown by a block of code.
function dosomething() {
throw new Error(
‘a error is thrown custom message’);
}
function init() {
try {
dosomething();
}
catch (e) {
console.log(e);
}
console.log(
“After successful error handling”);
}
init();
Output:
Error: a error is thrown custom message
at dosomething (/home/cg/root/6422736/main.js:4:11)
at init (/home/cg/root/6422736/main.js:9:9)
at Object. (/home/cg/root/6422736/main.js:17:1)
at Object.Module._extensions..js (module.js:579:10)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
After successful error handling
Using callbacks
A callback is a function called at the completion of a certain task. Callbacks are widely used in Node.js as it prevents any blocking and allows other code to be run in the meantime.
The program does not wait for the file reading to complete and proceeds to print “Program Ended” while continuing to read the file.
If any error occurs like the file does not exist in the system then the error is printed after “Program Ended”, else the content of the file is outputted.
Example:
const fs = require(‘fs’);
fs.readFile(‘text.txt’, ‘utf8’, (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
Using promises and promise callbacks
Example:
const Promise = require(‘promise’);
const MongoClient = require(‘mongodb’).MongoClient;
const url = ‘mongodb://localhost/TestDB’;
MongoClient.connect(url)
.then(function (err, db) {
db.collection(‘Test’).updateOne({
“Name”: “Joe”
},
{
$set: {
“Name”: “Beck”
}
});
})
.catch(error => alert(error.message))
Using async-await
Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don’t explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.
In an async function, you can await any Promise or catch its rejection cause.
So if you had some logic implemented with promises:
async function fetchData() {
try {
const response = await fetch(‘<https://example.com/data>’);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}}
Conclusion
Error-handling is at the core of developing resilient Node.js applications. Understanding types of error, applying proper error-handling strategies, and adopting error-handling best practices allows a smooth user experience and a manageable code for developers. Make sure you are implementing strong error-handling practices from today onward, so you can save on future headaches!