Categories
Node.js Best Practices

Node.js Best Practices — Error Handling

Spread the love

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some best practices we should follow when writing Node apps.

Handle Errors

If there’s any chance that an error may occur with a piece of code, we should handle the error.

For example, if we have a change of promises, we should call catch with an error handler callback passed into it.

We can write:

doSomething()
  .then(doNextStage)
  .then(doMoreThins)
  .then(updateInterestedParties)
  .then(cleanUp)
  .catch(errorHandler);

We have the catch method with the errorHandler callback function passed into it.

The callback will be called when any of the promises in the chain throws an error.

Ensure our App Automatically Restarts

We should ensure that our app automatically restarts.

This way, we won’t have to do this ourselves when our app encounters an unhandled error.

We need a process manager like Nodemon, forever, or PM2 to do this.

The last 2 are for production usage.

Nodemon is used for development more often.

For instance, we can install PM2 globally with:

npm install pm2 -g

Then we can launch our Node app with:

pm2 start app.js

Cluster our App to Improve Performance and Reliability

We can course our app so that we have more than one instance of it.

This way, we can distribute the work across all cores.

We need this since Node apps run in a single process.

PM2 lets us do this easily by running:

pm2 start app.js -i max

This lets us run multiple processes equal to the number of cores present in the server.

The processes don’t share memory or resources.

They’ll all have their own connection to the database, for instance.

Therefore, we should use something like Redis to keep session state across all instances.

Require All Dependencies Upfront

It’s a good idea to have our require calls all at the top so we won’t have to look for them in various parts of our code.

Also, we can spot any issues with them earlier.

For example, we can write:

const datastore = require("db")(someConfig);

app.get("/my-service", (request, response) => {
  db.get(req.query.someKey)
  // ...
});

We call require at the top so that we run them all earlier.

If there’re any errors with them, they’ll be thrown at the beginning.

Also, require is synchronous, so if it takes a long time to run, it’ll hold up our app.

If there any problems like these, we’ll find them early if we require them early.

Use a Logging Library to Increase Errors Visibility

Errors can happen in any environment.

And we want them to be visible so that we can fix them.

console.log is very limiting in a production setting.

A better logging library can give us more control over how to log.

We can have various types of logging or save the data somewhere.

Some good libraries include Loggly and Winston. Winston is the base package for basic logging.

And Node-Loggly uses Winston for logging.

This way, we’ll see the errors in one central place that’s searchable.

Conclusion

Error handling can be made easy with a few changes to our code.

We should catch errors and log them so we can fix them is needed.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *