MeWrite Docs

Failed to fetch - リクエストキャンセル(Abort)

AbortControllerによるリクエストキャンセルで発生するFailed to fetchエラーの原因と解決策

概要

ページ遷移やAbortControllerによりリクエストがキャンセルされた場合に発生します。これは正常な動作の場合もあれば、意図しないキャンセルの場合もあります。

この原因かどうかの確認方法

1
2
3
4
5
6
7
8
9
try {
  await fetch('/api/data');
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('リクエストがキャンセルされました');
  } else {
    console.error('Failed to fetch:', error);
  }
}

解決策

1. ReactのuseEffect内でクリーンアップする

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
useEffect(() => {
  const controller = new AbortController();

  fetch('/api/data', { signal: controller.signal })
    .then(res => res.json())
    .then(setData)
    .catch(err => {
      if (err.name !== 'AbortError') {
        setError(err);
      }
    });

  // クリーンアップ関数でリクエストをキャンセル
  return () => controller.abort();
}, []);

2. タイムアウトを適切に設定する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
async function fetchWithTimeout(url, timeout = 10000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, { signal: controller.signal });
    clearTimeout(timeoutId);
    return response;
  } catch (error) {
    clearTimeout(timeoutId);
    if (error.name === 'AbortError') {
      throw new Error(`Request timed out after ${timeout}ms`);
    }
    throw error;
  }
}

3. AbortErrorを適切にハンドリング

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
async function apiFetch(url, options = {}) {
  try {
    const response = await fetch(url, options);
    return await response.json();
  } catch (error) {
    if (error.name === 'AbortError') {
      // キャンセルは正常な動作なので、nullを返すかログのみ
      console.log('リクエストがキャンセルされました');
      return null;
    }
    // その他のエラーは再throw
    throw error;
  }
}

よくある間違い

  • useEffect内でAbortControllerを使わずにfetchを呼び出す(メモリリーク)
  • AbortErrorを他のエラーと同様に扱う
  • タイムアウトを短く設定しすぎる

まだ解決しない場合

診断ハブに戻る

関連エラー

関連エラー

JavaScript の他のエラー

最終更新: 2026-02-04