MeWrite Docs

Uncaught (in promise) TypeError

Promiseチェーン内で発生したTypeErrorがキャッチされなかった場合のエラー

概要

Uncaught (in promise) TypeError は、Promise内で発生したTypeErrorが .catch()try-catch で捕捉されなかった場合に発生するエラーです。非同期処理のエラーハンドリング漏れが原因で、Node.jsではプロセスのクラッシュにつながる可能性があります。

エラーメッセージ

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'map')
Uncaught (in promise) TypeError: Failed to fetch
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'data' of undefined

原因

  1. Promiseチェーンの.catch()漏れ: thenの後にcatchを付け忘れている
  2. async/awaitのtry-catch漏れ: awaitの呼び出しがtry-catchで囲まれていない
  3. fetch APIのレスポンスチェック漏れ: レスポンスがokでないケースを処理していない
  4. Promise.allの一部が失敗: 複数のPromiseのうち一つが拒否された
  5. イベントハンドラ内の非同期処理: イベントリスナー内のasync関数のエラーが伝播しない

解決策

1. Promiseチェーンに.catch()を追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// ❌ catchがない
fetch("/api/users")
  .then((res) => res.json())
  .then((data) => renderUsers(data));

// ✅ catchを追加
fetch("/api/users")
  .then((res) => res.json())
  .then((data) => renderUsers(data))
  .catch((error) => {
    console.error("ユーザー取得に失敗:", error);
    showErrorMessage("データの読み込みに失敗しました");
  });

2. async/awaitにtry-catchを追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// ❌ try-catchがない
async function fetchUsers() {
  const response = await fetch("/api/users");
  const data = await response.json();
  return data.users.map((u: any) => u.name); // dataがundefinedならエラー
}

// ✅ try-catchで囲む
async function fetchUsers(): Promise<string[]> {
  try {
    const response = await fetch("/api/users");

    if (!response.ok) {
      throw new Error(`HTTP Error: ${response.status}`);
    }

    const data = await response.json();
    return data.users?.map((u: any) => u.name) ?? [];
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error("ユーザー取得エラー:", error.message);
    } else {
      console.error("ユーザー取得エラー:", error);
    }
    return [];
  }
}

3. fetchレスポンスのステータスチェック

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// ❌ レスポンスのステータスを確認していない
async function getData() {
  const res = await fetch("/api/data");
  const json = await res.json(); // 404でもjsonをパースしようとする
  return json.items;
}

// ✅ ステータスコードを確認
async function getData(): Promise<Item[]> {
  const res = await fetch("/api/data");

  if (!res.ok) {
    throw new Error(`APIエラー: ${res.status} ${res.statusText}`);
  }

  const json = await res.json();
  return json.items ?? [];
}

4. グローバルなunhandledrejectionハンドラ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// ブラウザ環境
window.addEventListener("unhandledrejection", (event) => {
  console.error("未処理のPromise拒否:", event.reason);
  // エラー報告サービスに送信
  reportError(event.reason);
  // デフォルトのコンソール出力を抑制(必要に応じて)
  event.preventDefault();
});

// Node.js環境
process.on("unhandledRejection", (reason, promise) => {
  console.error("未処理のPromise拒否:", reason);
  // 本番環境ではプロセスを安全に終了
  // process.exit(1);
});

5. Promise.allSettledで部分的な失敗を許容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ❌ 一つでも失敗すると全体が失敗
const results = await Promise.all([
  fetchUser(1),
  fetchUser(2),
  fetchUser(3), // これが失敗すると全体がreject
]);

// ✅ allSettledで個別に結果を処理
const results = await Promise.allSettled([
  fetchUser(1),
  fetchUser(2),
  fetchUser(3),
]);

const users = results
  .filter((r): r is PromiseFulfilledResult<User> => r.status === "fulfilled")
  .map((r) => r.value);

const errors = results
  .filter((r): r is PromiseRejectedResult => r.status === "rejected")
  .map((r) => r.reason);

if (errors.length > 0) {
  console.warn("一部のユーザー取得に失敗:", errors);
}

関連エラー

JavaScript の他のエラー

最終更新: 2026-02-03