UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block

I am getting following error in my Node-Express App

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)

To say the least, I have created a helper function which looks something like this

const getEmails = (userID, targettedEndpoint, headerAccessToken) => {
return axios.get(base_url + userID + targettedEndpoint,  { headers: {"Authorization" : `Bearer ${headerAccessToken}`} })
.catch(error => { throw error})
}

and then I am importing this helper function

const gmaiLHelper = require("./../helper/gmail_helper")

and calling it inside my api route like this

router.get("/emailfetch", authCheck, async (req, res) => {
//listing messages in users mailbox
let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
.catch(error => { throw error})
emailFetch = emailFetch.data
res.send(emailFetch)
})

From my end, I think I am handling the error by using catch block.

Question: Can someone explain me why I am getting the error and how can I fix it?

303875 次浏览

I suggest removing the below code from getMails

 .catch(error => { throw error})

In your main function you should put await and related code in Try block and also add one catch block where you failure code.


you function gmaiLHelper.getEmails should return a promise which has reject and resolve in it.

Now while calling and using await put that in try catch block(remove the .catch) as below.

router.get("/emailfetch", authCheck, async (req, res) => {
//listing messages in users mailbox
try{
let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
}
catch (error) {
// your catch block code goes here
})

You are catching the error but then you are re throwing it. You should try and handle it more gracefully, otherwise your user is going to see 500, internal server, errors.

You may want to send back a response telling the user what went wrong as well as logging the error on your server.

I am not sure exactly what errors the request might return, you may want to return something like.

router.get("/emailfetch", authCheck, async (req, res) => {
try {
let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
emailFetch = emailFetch.data
res.send(emailFetch)
} catch(error) {
res.status(error.response.status)
return res.send(error.message);
})


})

This code will need to be adapted to match the errors that you get from the axios call.

I have also converted the code to use the try and catch syntax since you are already using async.

.catch(error => { throw error}) is a no-op. It results in unhandled rejection in route handler.

As explained in this answer, Express doesn't support promises, all rejections should be handled manually:

router.get("/emailfetch", authCheck, async (req, res, next) => {
try {
//listing messages in users mailbox
let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
emailFetch = emailFetch.data
res.send(emailFetch)
} catch (err) {
next(err);
}
})

I resolve the problem. It's very simple . if do you checking care the problem may be because the auxiliar variable has whitespace. Why ? I don't know but yus must use the trim() method and will resolve the problem

use express-async-errors on your app

like this

app.ts

import 'express-async-errors'

Later,configure your application to read the instance of error.

class Custom Error

class Error{
  

public readonly message: string;
public readonly statusCode: number;
public readonly data?: any


constructor(message: string, statusCode = 400, data?: any){
this.message = message;
this.statusCode = statusCode;
this.data = data;
}
}


export default Error

Middleware to use on your app -> app.use(youMiddleware())

import { Request, Response, NextFunction } from 'express'
import AppError from '../errors/AppError'


function globalErrors(err: Error, request: Request, response: Response, next: NextFunction) {


if (err instanceof AppError) {
response.status(err.statusCode).json({
status: 'error',
message: err.message,
data: err?.data
});
}


console.error(err);


return response.status(500).json({
status: 'error',
message: 'Internal server error'
});


}


export { globalErrors };