Asynchronous Error & Exception Handling in Node.js

We'll practice asynchronous error handling in this tutorial. You may experience a problem when creating a JavaScript function.

Being human, dealing with occasional mistakes is only natural and expected.

When the JavaScript interpreter is unable to run or execute a certain piece of code, errors are objects that are presented. There are three main types of errors, which include:

  • Logical errors: occur due to incorrect program logic. This error might be difficult to debug.
  • Runtime errors: These mistakes happen throughout the course of the program's life cycle and after the compiler has parsed the code (runtime).
  • Syntax errors: This is the most frequent mistake made in JavaScript since it is simple to do and results from wrong or missing linguistic syntax.

The JavaScript engine will stop running if a given piece of code encounters an error and display an error message, informing the user that an abnormal circumstance known as a "Exception" has been formed.

You could make a mistake in your code if you omit a colon or a curly brace somewhere.

It is imperative practice to always handle problems that might be thrown in our application since as node.js developers, we are frequently presented with failures from either the server or the client.

admin-async-await-javascript.jpg

JavaScript's asynchronous programming feature enables you to run multiple processes concurrently without needing to wait for one to finish before going on to the next.

I'll walk you through locating and avoiding Node.js errors in this tutorial.

How to identify errors

errorwhite.jpeg Any standard error always throws an object which includes two basic properties;

  1. name: Sets or returns an error name.
  2. message: Returns an error message in the string form.

Prior to identifying difficulties, it is crucial to comprehend the numerous sets of terms associated with JavaScript.

Throw: In the JavaScript runtime, errors and exceptions are generated using the throw keyword. The throw keyword can display objects, strings, and integers, although it's not a good idea to toss strings or numbers.

Numbers and strings are primitive in nature in that there do not carry any information about errors or debugging information.

try…catch: It is important to remember that the catch block must always come after the try block in order to function properly. This keyword is used to signal that a specific code block may throw an exception.

try…catch…finally: The finally keyword is used to specify a course of action to be taken after an error has been encountered; even if the code is not successfully performed by the try...catch statement, the finally keyword must still be executed.

Basic error handling

const newUser = (req, res) => {
    const { name, email, password} = req.body

    if (!name || !email || !password) {
        res.status(400)
        throw new Error ('Incorrect login details')
    }
    res.send()
}

An easy function to throw an error originating from a database API is represented by the code above.

Keep in mind that the toss keyword causes an exception when the user's name, username, or password are either missing or incorrect. This function is not asynchronous.

const handleError = (err, req, res, next) => {

const status = res.status ? res.status : 500
res.status(status)
res.json({
    message: err.message,

})
}

module.export = {handleError}

Create an error middleware in the NodeJS app and then import it into your server to handle the error globally, res.status() is set to the error thrown from newuser() above.

Asynchronous Error handling

To handle an error asynchronously, make use of the try…catch keyword or more preferably, a useful and more efficient tool called the express-async-handler.

It initiates middleware for handling exceptions inside of async express routes and passing them to your express error handlers.

trycatch.png

Try…Catch

const newUser = (req, res) => {
    const { name, email, password} = req.body 
  try {
     if (!name || !email || !password) {
        res.status(400)
        throw new Error ('Incorrect login details')
    }

    res.send()

} catch (Error) {
    console.log(Error)

}
}

The above code block makes use of the try…catch keyword to first try the conditional IF statement, if false the catch(Error) takes in the error and generates an exception.

express-async-handler

Express-async-handler is a straightforward, user-friendly, and effective utility for asynchronous error handling.

Let's begin by installing the module to use the express-async-handler package to handle problems.

**npm install –save express-async-handler**

The command above will install the dependency into our express application, the way we use it is very easy, simply wrap the given code block with the asyncHandler() function.

const asynHandler = require(‘express-async-handler’)

const newUser = asynchandler(async (req, res) => {
    const { name, email, password} = req.body

    if (!name || !email || !password) {
        res.status(400)
        throw new Error ('Incorrect login details')
    }
    res.send()
}

Conclusion

In each given use case, it is recommended to always deal with async functions to handle problems. Even in smaller applications, having too many "try..catch" blocks can make your code problematic and challenging to maintain.

Async try…catch block Functions makes our code linear and very easy to debug.