MeWrite Docs

UnhandledPromiseRejection: Promise rejection was not handled

Promiseがrejectされたが.catchで処理されなかった場合のエラー

概要

Promiseがrejectされたにもかかわらず、.catch()やtry-catchで処理されなかった場合に発生するエラーです。Node.js 15以降ではプロセスがクラッシュします。

エラーメッセージ

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

原因

  1. catchの付け忘れ: Promiseに.catch()を付けていない
  2. async関数のtry-catch不足: async関数内でawaitしたPromiseのエラーを捕捉していない
  3. Promise.allの一部失敗: 複数のPromiseのうち1つが失敗した
  4. イベントリスナー内のPromise: イベントハンドラ内でawaitしたPromiseのエラー

解決策

1. .catch()を追加

1
2
3
4
5
6
7
// Bad
fetchData().then(data => console.log(data));

// Good
fetchData()
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

2. async/awaitでtry-catch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Bad
async function getData() {
  const data = await fetchData(); // エラーが伝播しない
  return data;
}

// Good
async function getData() {
  try {
    const data = await fetchData();
    return data;
  } catch (error) {
    console.error('Error:', error);
    throw error; // 必要に応じて再throw
  }
}

3. Promise.allSettledを使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Bad: 1つでも失敗すると全体が失敗
const results = await Promise.all([
  fetch('/api/1'),
  fetch('/api/2'),
  fetch('/api/3')
]);

// Good: 各Promiseの結果を個別に取得
const results = await Promise.allSettled([
  fetch('/api/1'),
  fetch('/api/2'),
  fetch('/api/3')
]);

results.forEach((result, i) => {
  if (result.status === 'fulfilled') {
    console.log(`API ${i}: ${result.value}`);
  } else {
    console.error(`API ${i} failed:`, result.reason);
  }
});

4. グローバルハンドラの設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Node.js
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection:', reason);
  // ロギングやアラート送信
});

// ブラウザ
window.addEventListener('unhandledrejection', (event) => {
  console.error('Unhandled Rejection:', event.reason);
  event.preventDefault(); // デフォルトの警告を抑制
});

5. イベントハンドラでの対処

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Bad
button.addEventListener('click', async () => {
  const data = await fetchData(); // エラーが捕捉されない
});

// Good
button.addEventListener('click', async () => {
  try {
    const data = await fetchData();
  } catch (error) {
    console.error('Click handler error:', error);
  }
});

6. Express.jsでのエラーハンドリング

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Bad
app.get('/api', async (req, res) => {
  const data = await fetchData(); // エラーで応答なし
  res.json(data);
});

// Good
app.get('/api', async (req, res, next) => {
  try {
    const data = await fetchData();
    res.json(data);
  } catch (error) {
    next(error); // エラーミドルウェアに渡す
  }
});

よくある間違い

  • .then().then().catch()で途中のthenでエラーが発生してもcatchで捕捉されると誤解
  • async関数を呼び出す側でエラーハンドリングを忘れる
  • Promise.allで1つの失敗が全体に影響することを見落とす

関連エラー

参考リンク

JavaScript の他のエラー

最終更新: 2025-12-13