top of page
Writer's pictureDibyojyoti Sanyal

Error Handling with HTTP Error Response Generation in node.js Application

In one of my blog posts (Separate routing from business logic in node.js | Central response generation in node.js) we have seen how we can perform central HTTP response generation from the responses generated by the business logic module. In application different error conditions can occur. We would like to code for those error conditions using a try-catch, and throw constructs provided by the programming language. But that is not good when it comes to HTTP error responses. In cloud native application development we need to convert those errors to HTTP error responses. It would be necessary to handle the throws exceptions from code and convert them to HTTP error responses centrally. In this post we will see how to do that exactly.


 

Contents

 

The application Server

node-app-server.js

const express = require('express');
const app = express();
const port = 5000;
const userRouter = require('./routes/user.js')();
app.use(userRouter);

app.listen(port, () => {
  console.log(`My app listening at http://localhost:${port}`);
});

The Router


routes/user.js

const router = require('express').Router();
const processResponse = require('../responseHandler')();
const User = require('../model/User')();

module.exports = function () {
  router.get('/user/:id', processResponse(User.fetch));
  return router;
}

The Response Handler


The Business logic

model/User.js

function User() {

  return Object.freeze({
    fetch,
    create
  });

  async function fetch(request) {
    if(isNaN(request.params.id)) {
      throw new TypeError("id '"  + request.params.id + 
        "' not a number, not valid ");
    }
    return 'Hello World From User Get ' + request.params.id;
}

See the User.js model containing the business logic. We have enhanced the fetch() method with a request parameter checking. The IF statement verifies whether the ID in the request URL is a number. It throws a TypeError if it's not a number. We would like to add this kind of validation and throw error but how will the response look like when an error is thrown?


Let’s send a GET request to the user endpoint http://localhost:5000/user/abcd


We will get the full error stack in the browser as a response.

Error: id 'abcd' not a number, not valid
  at fetch (C:\<path>\node_test\model\User.js:10:10)
  at C:\<path>\node_test\requestHandler.js:23:37
  . . .

But we want to provide the end user a nicely formed error response. How can we do that ?


The Central Error Handler

At first we write an error handler errorHandler.js

function errorHandler() {
  return (err, req, res, next) => {
    if (err instanceof TypeError) {
      return res.status(400).json(err.name + ": " + err.message);
    }
    if (err && err.statusCode) {
      return res.status(err.statusCode).json(err.body);
    }
    return next(err);
  }
}

module.exports = errorHandler;

In the application server file node-app-server.js we need to add the errorHandler as shown here.

const express = require('express');
const app = express();
const port = 5000;
const userRouter = require('./routes/user.js')();
const orderRouter = require('./routes/order.js')();
const processError = require('./errorHandler')();

app.use(userRouter);
app.use(orderRouter);
app.use(processError);

app.listen(port, () => {
  console.log(`My app listening at http://localhost:${port}`);
});

Lets access the same endpoint after we run the application with this code. Let's call the same endpoint with a user id “abcd”. The GET request looks like http://localhost:5000/user/abcd


The returned error message will be

"TypeError: id 'abcd' not a number, not valid" 

with HTTP return code 400.


Today, we have learned how we can handle thrown errors from anywhere in the code centrally in node js application and formulate a suitable http error response.



Recent Posts

See All

Comments


bottom of page