web-dev-qa-db-ja.com

UnhandledPromiseRejectionWarning:このエラーは、catchブロックなしで非同期関数の内部をスローすることによって発生しました

Node-Expressアプリで次のエラーが発生します

UnhandledPromiseRejectionWarning:未処理のプロミス拒否。このエラーは、catchブロックなしで非同期関数の内部をスローしたか、.catch()で処理されなかったpromiseを拒否したことにより発生しました。 (拒否ID:4)

控えめに言っても、私はこのようなヘルパー関数を作成しました

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

そして、私はこのヘルパー関数をインポートしています

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

そして、このように私のAPIルートの中でそれを呼び出す

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)
})

私の側からは、catchブロックを使用してエラーを処理していると思います。

質問:なぜエラーが発生するのか、どうすれば修正できるのか、誰か説明してもらえますか?

24
anny123

.catch(error => { throw error})は何もしません。その結果、ルートハンドラで未処理の拒否が発生します。

この答え で説明されているように、Expressはpromiseをサポートしていません。すべての拒否は手動で処理する必要があります。

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);
  }
})
17
Estus Flask

GetMailsから以下のコードを削除することをお勧めします

 .catch(error => { throw error})

メイン関数では、待機ブロックと関連コードをTryブロックに配置し、コードの失敗箇所に1つのcatchブロックを追加する必要があります。


関数gmaiLHelper.getEmailsは、拒否して解決するpromiseを返す必要があります。

Awaitを呼び出して使用しているときに、次のようにtry catchブロック(.catchを削除)に入れます。

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
})
4
Sumer

あなたはエラーをキャッチしていますが、それからそれを再び投げています。より適切に処理する必要があります。そうしないと、ユーザーに500、内部サーバー、エラーが表示されます。

サーバーにエラーを記録するだけでなく、何が問題かをユーザーに知らせる応答を送り返すことができます。

リクエストが返す可能性のあるエラーは正確にはわかりません。

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);
    })

})

このコードは、axios呼び出しで発生するエラーと一致するように調整する必要があります。

また、既に非同期を使用しているため、try and catch構文を使用するようにコードを変換しました。

2
tmcnicol