JavaScript | 「例外+非同期」のデバッグ実践(Promise の中のエラー追跡)

JavaScript
スポンサーリンク

では、非同期 fetch + try/catch + ブレークポイント + UI 表示のフル連動デモ を作ります。
このサンプルでは、複数 URL の取得結果を 成功/失敗で色分けして表示 し、DevTools でブレークポイントを使ってステップ実行できるようにします。


実演コード:非同期 fetch × try/catch × UI表示

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>非同期Fetchデバッグフルデモ</title>
  <style>
    body { font-family: sans-serif; }
    .success { color: green; }
    .error { color: red; }
  </style>
</head>
<body>
  <h1>非同期Fetch デバッグデモ</h1>
  <button id="loadBtn">データを取得</button>
  <ul id="resultList"></ul>

  <script>
    const resultList = document.getElementById("resultList");

    async function fetchDataWithUI() {
      const urls = [
        "https://jsonplaceholder.typicode.com/todos/1",
        "https://jsonplaceholder.typicode.com/todos/2",
        "https://invalid.example.com/data.json" // 故意にエラー
      ];

      resultList.innerHTML = "";
      try {
        // ブレークポイント候補: Promise作成直後
        const fetchPromises = urls.map(url =>
          fetch(url)
            .then(res => {
              if (!res.ok) throw new Error(`HTTPエラー: ${res.status} (${url})`);
              return res.json();
            })
        );

        // ブレークポイント候補: Promise.all 待機
        const results = await Promise.allSettled(fetchPromises);

        results.forEach((result, idx) => {
          const li = document.createElement("li");
          if (result.status === "fulfilled") {
            li.textContent = `✅ 成功: ${urls[idx]}${JSON.stringify(result.value)}`;
            li.className = "success";
          } else {
            li.textContent = `❌ 失敗: ${urls[idx]}${result.reason}`;
            li.className = "error";
          }
          resultList.appendChild(li);
        });

      } catch (err) {
        // ブレークポイント候補: try/catch で捕捉
        console.error("例外発生:", err);
      } finally {
        console.log("全処理終了");
      }
    }

    document.getElementById("loadBtn").addEventListener("click", fetchDataWithUI);
  </script>
</body>
</html>
HTML

2. デバッグ手順

  1. F12 → Sources タブ を開く
  2. ブレークポイント候補:
    • const fetchPromises = urls.map(...);(Promise 作成直後)
    • const results = await Promise.allSettled(fetchPromises);(await 後)
    • console.error("例外発生:", err);(catch ブロック)
  3. 「データを取得」ボタンをクリック
  4. ブレークポイントで停止 → ステップ実行
    • ステップオーバーで 1行ずつ確認
    • Scope/Watch で urlsfetchPromisesresults の値を確認

3. ポイント解説

非同期と UI の連動

  • 成功/失敗ごとに <li> を作成して表示
  • 成功は緑、失敗は赤で色分け → どの URL が失敗したか即確認可能

デバッグの観察ポイント

  • fetchPromises の中身を Watch に追加 → Promise 状態を確認
  • results の中身を確認 → fulfilled / rejected が分かる
  • ブレークポイントで停止 → 各 fetch の返り値を逐次確認可能

Promise.allSettled の利点

  • 1つの失敗で全体が止まらず、すべての結果を UI に反映できる

4. 追加テクニック

  1. 条件付きブレークポイント:
    • 失敗した URL だけ止めたい場合、条件式に result.status === "rejected" を設定
  2. ステップ実行で非同期挙動を理解:
    • Promise.allSettled 内の各 fetch の完了タイミングを追跡
  3. console.trace() を活用: console.trace("fetch完了時の呼び出し経路");

5. 学習ポイントまとめ

ポイント内容
非同期 fetch のエラー処理try/catch + Promise.allSettled
UI連動成功/失敗を色分け表示して直感的に確認
ブレークポイントPromise 作成直後・await 後・catch ブロックに設定
Scope/Watchurls、fetchPromises、results をリアルタイム観察
Async Stack Traceどの非同期処理で失敗したか追跡可能

💡 このサンプルをさらに発展させると:

  • 部分的に成功した結果だけ UI に反映
  • 失敗時にリトライボタンを表示
  • 複数ボタンで異なる API を同時にテスト

など、実務レベルの非同期デバッグ演習が可能です。

タイトルとURLをコピーしました