javascriptnode.jserror-handlingbackendserver-error

NodeJS API await got(options) error Handling Not Sending Error To Frontend


I have an API in nodejs that start from the controller, routes to the service to complete the request, returns the response to the controller to process and send back to the frontend. I am having a little trouble with the error handling of it. If the got(options) method fails, I get a 500 internal error. If I attach a catch to the got(options) functions such as:

const response = await got(options).catch(err=>{
console.log('error ' +err.message);
console.log('error ' +JSON.stringify(err.body));
});

The error logs but I cannot send the error to the frontend and get a 500 error on the API call instead. I tried multiple ways but am new to error handling and couldn't get it to work.

My controller code is:

  router.delete('/deletePayment/:id', (req, res, next) => {
  squarePaymentService.deletePayment(req.params.id)
    .then(paymentResponse => res.send(paymentResponse))
    .catch(err => next(err));
  });

The service code is:

 async function deletePayment(paymentId) {

  const options = await ApiOptionsService.deleteItem(paymentId)

  const response = await got(options).catch(err=>{
    console.log('error ' +err.message); //need to catch and send this error to frontend.
  });
  return response.body;
}

I want to catch the error in console.log('error ' +err.message); and send it to the frontend.


Solution

  • Your .catch() handler in deletePayment() is "eating" or "handling" the error and thus the error does not propagate back to the caller. It logs it, but does nothing else thus changing the rejection into a resolved promise. The caller thinks the operation succeeded.

    If you want the error to propagate which it sounds like you do, then you need to rethrow the error after logging it.

    async function deletePayment(paymentId) {
    
      const options = await ApiOptionsService.deleteItem(paymentId)
    
      const response = await got(options).catch(err=>{
        console.log('error ' +err.message); 
        // re-throw the error so the caller will get it
        throw err;
      });
      return response.body;
    }
    

    But, this code is only logging some errors and is mixing await with .catch() which is generally not favored. If you want to log any errors in this function, I'd do it like this:

    async function deletePayment(paymentId) {
        try {
            const options = await ApiOptionsService.deleteItem(paymentId)
            const response = await got(options);
            return response.body;
        } catch(err) {
            // log error
            console.log('error ' + err.message);
            // rethrow so caller gets rejection
            throw err;
        }
    }