1

I have an existing Node Express Application and want to improve the error handling better. My current route endpoint definition is like below,

app.get('/example/getActiveId', async (req, res, next) => {
  // Some code to fetch some details from request and do some validations

  try {
    const result = await api.getActiveId(id); 
    res.json({ success: true, result });       // I am getting this response in all the time.
  } catch (err) {
    console.log('getActiveId', err)
    console.error(err);
    res.json({ success: false });
  }
});

Also, I defined error middleware at the last of all the route paths.

// error handler middleware
app.use((error, req, res, next) => {
  console.log('in Error middleware')
  console.error(error.stack);
  res.status(500).send(error.message || 'Something Broke!');
 })

My definition of getActiveId is as below.

 exports.getActiveId = id => axiosInstance
  .get('/example')
  .then(({ data }) => data)
  .catch(er => er);

The problem in the above getActiveId definition is every time the catch of the getActiveId, the execution falls into the try block of the above endpoint definition. I wanted the execution should go into the catch block endpoint definition function. So that I could call next(err) to call the default express error handling middleware.

So I tried the following mockup code to mimic the same with promise reject.

exports.getActiveId = id => {
    const __mockPromise = () => {
        return new Promise((resolve, reject) => {
            reject('Problem in getActiveId')
        })
    }

    return new Promise((resolve, reject) => {
        __mockPromise().then(({ data }) => resolve(data)).catch(er => { console.log('in catch....'); reject(er) })
    });
}

I expected the above function will go into the catch block of the end point function definition.

But this time I am getting the following error,

in catch....
(node:32897) UnhandledPromiseRejectionWarning: Problem in getActiveId
(node:32897) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)

How can I fix this error and bypass the execution to error middleware?

Smith Dwayne
  • 2,675
  • 8
  • 46
  • 75

1 Answers1

0

With your current code, api.getActiveId always returns a resolved promise

  • if the axiosInstance.get succeeds, it resolves to the data
  • if the axiosInstance.get fails, the .catch(er => er) makes it resolve to the er.

If you want api.getActiveId to return a promise that is rejected with er, omit the .catch(er => er).

For example, if you run Node.js with the following input

const getActiveId = () => Promise.reject("error")
  .then(({ data }) => data);
async function test() {
  try {
    const result = await getActiveId();
    console.log(result);
  } catch (err) {
    console.error(err);
  }
}
test();

the console.error statement will be reached and no unhandled promise rejection will be reported.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • Can we do the same with the Mock function? If I do your steps above, I am getting, ```Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)``` – Smith Dwayne Oct 26 '21 at 13:42
  • I don't understand the purpose of your mock function. If `api.getActiveId` returns a rejected promise, the `catch` in your async middleware will handle that. – Heiko Theißen Oct 26 '21 at 13:50
  • I couldn't send make the error case of axis instance. So I made a mockup function which able to post a reject call and test my code. But its not working as the way it should. – Smith Dwayne Oct 26 '21 at 14:06
  • Indeed, when I try the same, the rejection is handled by my `catch` block. – Heiko Theißen Oct 26 '21 at 14:07
  • But I am getting all the responses to try block of API endpoint definition. means, I am getting {success: true}. But for failure response of Axios call (or) mockup call, I need to get {success: false} – Smith Dwayne Oct 26 '21 at 14:28
  • When I run this: `const getActiveId = () => Promise.reject("error") .then(({ data }) => data); async function test() { try { const result = await getActiveId(); console.log(result); } catch (err) { console.error(err); } } test();`, I get to the `console.error`, no unhandled promise. Same for you? – Heiko Theißen Oct 26 '21 at 14:56
  • ```Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3) ``` getting this – Smith Dwayne Oct 26 '21 at 16:37