2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるエラーハンドリング戦略:try-catch、ユーザー通知、復旧・ログ出力と安全な終了設計

Posted at

概要

エラーハンドリングとは「止める」ことではない。
それは**「壊さず、知らせ、回復可能な構造にする」ための設計行為**である。

JavaScriptの実行環境は多様で不確実。
同期・非同期・UI・ネットワークあらゆる箇所で例外が発生しうる。

本稿では、予期可能な失敗の吸収と通知、UIの安全な設計、ログによる分析性の担保を含めた、壊れないアプリケーション設計を提示する。


1. try-catch の適用範囲は最小単位に

try {
  const data = JSON.parse(raw);
} catch (e) {
  console.error('JSONパース失敗:', e);
}
  • try-catchの範囲を小さくすることで局所的にエラーを制御
  • ❌ アプリ全体を包むようなcatch構造 → 障害原因が特定不能に

2. 非同期関数での明示的エラーフロー設計

async function fetchUser() {
  try {
    const res = await fetch('/api/user');
    if (!res.ok) throw new Error('通信エラー');
    return await res.json();
  } catch (e) {
    throw new Error(`ユーザー取得失敗: ${e.message}`);
  }
}
  • ✅ ネットワークの成功でもres.okをチェック
  • ✅ エラーを補足して明示的なメッセージ化

3. ユーザー通知と開発ログは目的を分ける

✅ ユーザーには簡潔に

showError('サーバーと通信できませんでした');

✅ 開発者向けには詳細ログ

console.error('Fetch failed:', e, context);

→ ✅ ユーザーの混乱を防ぎつつ、調査可能な情報を記録


4. グローバル例外フックの設計

window.onerror = function (msg, url, line, col, error) {
  sendLog({ msg, url, line, col, stack: error?.stack });
};

window.onunhandledrejection = function (event) {
  sendLog({ reason: event.reason });
};
  • 未処理の例外・Promiseエラーも捕捉可能
  • ✅ ログに加え、ユーザーへの再読み込み提案なども実装可能

5. リトライ戦略と安全なフォールバック

async function retry(fn, limit = 3) {
  for (let i = 0; i < limit; i++) {
    try {
      return await fn();
    } catch (e) {
      if (i === limit - 1) throw e;
    }
  }
}
  • ✅ 通信系の一時的失敗に対して限定的な再試行
  • ✅ 最後にはフォールバックデータを表示 or 再接続ボタンを提供

6. 意図的な失敗の伝播設計

function validateInput(value) {
  if (!value) throw new ValidationError('入力が空です');
}
  • ✅ **ドメインエラー(入力ミス・状態不整合)**は意図的にthrow
  • ValidationError, NotFoundErrorなどカスタムエラーで粒度を明示

設計判断フロー

① try-catchの範囲が広すぎないか? → 小さい関数単位で設計

② catch後にログとユーザー通知を分けているか? → 目的を区別

③ ネットワーク失敗が検知可能になっているか? → res.okチェック

④ 再試行やフォールバックが存在しているか? → retry構造を用意

⑤ 予期しうるエラーを例外として設計しているか? → カスタムエラー導入

よくあるミスと対策

❌ try-catchで握りつぶして何も通知しない

→ ✅ ログ送信 + UIで明示的に通知


❌ 非同期エラーが await されず、気づかない

→ ✅ Promiseを必ずawait or catchで制御


❌ 例外の種類が曖昧で、処理分岐ができない

→ ✅ カスタムエラーで意味付けを明確に


結語

エラーハンドリングとは「失敗を防ぐこと」ではない。
それは**“失敗しても壊れない構造”をつくるための設計戦略**である。

  • エラーは発生する前提で設計し
  • 意図的に分類し
  • 最小限に影響を閉じ込める

JavaScriptにおけるエラーハンドリング設計とは、
“失敗を吸収し、回復可能にするための構造化された防御”である。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?