peter.cambal
peter.cambal

Reputation: 522

NodeJs Express Response Handler

I am new to express (or any JS backend) so sorry if question was already answered, or kind of stupid.

I have registered endpoint.

app.get('/hello-world'), async (req, res) => {
    try {
        // do something
        sendResponse({"Message": "Hello World"}, res);
    } catch (e) {
        handleError(e, res);
   }
});

Where sendResponse and handleError are doing just setting status and body / additional exception metadata using res.status().json()

Is there any way to make response handling more simple by registering some response handler and write the logic of response / exception handling at one place?

What I have in mind is this:
Change example endpoint logic to:

 app.get('/hello-world'), async (req, res) => {
    return {"Message": "Hello World"}
    // or throw new error
});

and some repsonse handler which will handle result of function

resposeHandler(payload, err, res) {
    if (err) {
        res.status(500).json(err) // just as an example
    } else {
       res.status(200).json(payload)
    }
}

Upvotes: 1

Views: 4026

Answers (2)

Mudzia Hutama
Mudzia Hutama

Reputation: 504

create two middlewares, one for error handle and the other one for success response

// error handling when error occured
function errorHandler(req,res,next) => {
  return res.status(err.status || 500).json({
    success: false,
    message: err.message
  });
};

// success response and return data
function successHandler(successMsg, successData) => {
  return (req,res,next) => {
    return res.status(200).json({
      success: true,
      message: successMsg,
      data: successData
    });
  };
};

register them in express

const app = express();

app.get('/someroute', successHandler('it is endpoint of someroute!', 'your data here'))

app.use(errorHandler)

use errorHandler after you call and define the route

Upvotes: 1

Rashomon
Rashomon

Reputation: 6762

You can create a function wrapper to catch all the errors and send them to the error middleware:

const errorHandler = (routeHandler) =>
  (req, res, next) => {
    const routeHandlerReturn = routeHandler(req, res, next)
    return Promise.resolve(routeHandlerReturn).catch(next)
  }

Then you can reutilize it in all your controllers, making the app much cleaner:

app.get('/hello-world', errorHandler(async function(req, res, next) {
    sendResponse({"Message": "Hello World"}, res);
});

If some error is thrown, it will be handled in your error handler middleware:

// index.js
app.use((err, req, res, next) => {
  res.status(err.status || 500)
  res.json({
    message: err.message || 'Internal Error',
    error: err.error
  })
})

Upvotes: 1

Related Questions