JavaScript勉強3日目:fetchエラーハンドリング&リトライ/ESM/フォーム検証

1) fetch のエラーハンドリング&リトライ

要点は3つ:

  • HTTPエラーは res.ok を見る(200–299 以外は例外扱い)
  • ネットワーク/タイムアウト/5xx をリトライ(4xxは通常リトライしない)
  • タイムアウト+指数バックオフ+ジッターで“優しく再試行”

サンプルでは api.jsfetchWithRetry(url, options, { retries, backoff, factor, jitter, timeout, retryOn }) を実装。
retryOn で「どんな失敗を再試行するか」を関数で指定できます。

// 使い方(main.js)
const data = await fetchWithRetry(
  `https://jsonplaceholder.typicode.com/posts?_limit=${limit}`,
  {},
  {
    retries: 3, backoff: 500, factor: 2, jitter: true, timeout: 7000,
    retryOn: (err) => err?.message === 'Request timeout'
                    || err instanceof TypeError    // ネットワークなど
                    || (err?.status >= 500)        // サーバ5xx
  }
);

2) ES Modules でファイル分割

役割ごとに小さく

  • api.js … 通信とリトライ
  • validation.js … 入力チェック(純粋関数にしてテストしやすく)
  • dom.js … DOMユーティリティ
  • main.js … イベント配線&画面更新(副作用を集約)

HTML は <script type="module" src="./main.js"></script>
main.js 内で import { fetchWithRetry } from './api.js' のように読み込みます。


3) フォームのバリデーション & 軽いテスト

入力チェックは純粋関数で:validateSignup({ name, email }) => errors[]
UI側はそれを呼んで表示を切り替えるだけにします。

// validation.js
export function isNonEmpty(s){ return typeof s==='string' && s.trim().length>0; }
export function isEmail(s){ return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test((s||'').trim()); }
export function validateSignup({name,email}){
  const errors=[]; if(!isNonEmpty(name)) errors.push('お名前を入力してください');
  if(!isEmail(email)) errors.push('メールアドレスの形式が正しくありません');
  return errors;
}

console.assert で“壊れていないか”をさくっと確認:

console.assert(isNonEmpty('abc') === true);
console.assert(isEmail('a@b.com') === true);
console.assert(validateSignup({name:'', email:'bad'}).length >= 1);

失敗すると Console に赤字で出ます。まずはこのレベルのテストを日常に。


画面で試せること

  • 「投稿を読み込む」:通信成功/失敗/リトライの流れと、ステータス表示を体験
  • サインアップ風フォーム:必須チェック&メール形式 → OKなら成功メッセージ
  • Console を開くと console.assert の小テストログが見られます

次の一歩(お好みで)

  • fetchWithRetry「特定のHTTPコードだけ再試行」(429, 503)を追加
  • フォームに HTML標準の Constraint Validation APIinput.reportValidity() など)を併用
  • モジュールを ディレクトリごとに分け、index.js で再エクスポート
  • とくに失敗しやすい関数だけ Jest なしの“関数単体テストHTML” を別途用意
おすすめの記事