Node.js Basics — Error Handling

John Au-Yeung - Jan 22 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Node.js is a popular runtime platform to create programs that run on it.

It lets us run JavaScript outside the browser.

In this article, we’ll look at how to start using Node.js to create programs.

Error Handling

Most nontrivial programs will run into errors at some point.

Therefore, we got to handle them so that we can keep our programming running properly.

There’re a few ways to handle errors. One way is to use try-catch .

The others include catching them at the process or domain level.

To catch errors with try-catch , we just write:

function parseJSON(input) {  
  let json;  
  try {  
    json = JSON.parse(input);  
  } catch (error) {  
    return Promise.reject("Couldn't parse JSON");  
  }  
  return Promise.resolve(json);  
}
Enter fullscreen mode Exit fullscreen mode

We tried to parse JSON in our function with the JSON.parse method.

When there’s an error, we return a rejected promise with Promise.reject with the reason for rejection.

Otherwise, we return a resolved promise with the parsed json object.

We can catch errors when the uncaughtException event is emitted.

For example, we can write:

process.on('uncaughtException', function(error) {  
  logger.fatal(error);  
  logger.fatal('Fatal error encountered, exiting now');  
  process.exit(1);  
});
Enter fullscreen mode Exit fullscreen mode

We call process.on to watch for the uncaughtException event.

Then we call logger.fatal to log a fatal error.

And then call process.exit with code 1 to exit the program with an error code.

We should always exit the process following an uncaught error.

This is because the app is in an unknown state when an uncaught exception is raised.

A better way to catch errors is to catch them at the domain level.

To do that, we can use the domain package.

We install it by running:

npm i domain
Enter fullscreen mode Exit fullscreen mode

Then we can use it by writing:

const Domain = require('domain');    
const domain = Domain.create();  
domain.on('error', function(error) {  
  console.log('Domain error', error.message);  
});  
domain.run(function() {  
  console.log(process.domain === domain);  
  throw new Error('Error happened');  
});
Enter fullscreen mode Exit fullscreen mode

This prevents us from stopping the program whenever an error occurs.

We just catch errors happening in some domains instead of catching all errors.

We run any code that may raise errors in the domain.run callback so that we can catch errors.

If we have any async code, then we can run the async code in the domain.run method’s callback.

For example, we can write:

const Domain = require('domain');  
const domain = Domain.create();  
domain.on('error', function(error) {  
  console.log('Domain error', error.message);  
});  
process.nextTick(function() {  
  domain.run(function() {  
    throw new Error('Error happened');  
  });  
});
Enter fullscreen mode Exit fullscreen mode

to run the code for the nextTick callback in the domain.run ‘s callback instead.

Conclusion

There’re several ways to handle errors in a Node.js app.

One way is to use try-catch to catch the error.

Another way is to catch the error by listening to the uncaughtException event.

A better way to catch errors is to catch them by the domain.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .