2
2

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におけるエラーハンドリング設計:例外構造・エラー分類・通知設計・ユーザー体験の担保

Posted at

概要

エラーハンドリングとは“例外が起きたときに止める”ことではない。
それは“壊れても崩壊しないための設計”であり、開発者とユーザーの双方に意味あるフィードバックを返すための構造的判断である。

本稿では、JavaScriptにおけるエラーハンドリング設計を以下の観点で整理する:

  • try/catchの構造化と責務範囲
  • ドメインごとのエラー分類と再throw戦略
  • UIとエラーの分離・通知連携
  • ログ収集と監視との統合
  • 想定外のエラーに対する“最後の砦”設計

1. try/catchの構造と設計的境界

try {
  const res = await fetch('/api/user');
  const data = await res.json();
  render(data);
} catch (err) {
  showError('ユーザー情報の取得に失敗しました');
}
  • ✅ tryは**“例外が起こり得る最小範囲”**をカバー
  • ✅ catchはユーザー向けorログ向けの責務に分けて設計

2. エラーの分類とカスタムエラー設計

class AppError extends Error {
  constructor(message, code = 'APP_ERROR') {
    super(message);
    this.code = code;
  }
}

class ValidationError extends AppError {
  constructor(message) {
    super(message, 'VALIDATION_ERROR');
  }
}

→ ✅ catch時にエラー種別を判別して処理を分岐

try {
  validate(input);
} catch (e) {
  if (e instanceof ValidationError) {
    notifyUser(e.message);
  } else {
    logError(e);
  }
}

3. 非同期・チェーンの中でのエラー設計

async function load() {
  try {
    const data = await fetchUser();
    display(data);
  } catch (e) {
    report(e);
  }
}

.catch()は構造的責務で分ける

fetch('/api')
  .then(handleResponse)
  .catch(logError); // 全体的な責任

4. ユーザー体験に応じた通知設計

  • ✅ 軽微なエラー → トースト or 非同期通知
  • ✅ 重大な処理失敗 → モーダル or 再試行UI
  • ✅ バリデーション系 → input欄付近に個別表示
try {
  await save();
  showToast('保存に成功しました');
} catch {
  showToast('保存に失敗しました', { type: 'error' });
}

→ ✅ UIの破壊を避け、“伝わるフィードバック”を常に提供する


5. 例外監視とログの最終設計

✅ グローバルエラーのハンドリング

window.addEventListener('error', (event) => {
  reportFatalError(event.error);
});

window.addEventListener('unhandledrejection', (event) => {
  reportFatalError(event.reason);
});
  • ✅ 想定外の例外も収集・通知設計に統合
  • ✅ 例外発生位置・スタックトレース・ユーザー環境を含めて送信

設計判断フロー

① 例外が起きうる範囲は? → try/catchの範囲を絞る

② ユーザーに伝える必要がある? → UIと通知構造を分離

③ 同じcatchで全部処理してない? → エラー分類を導入

④ ログは必要? → スタック情報を含めて送出設計を入れる

⑤ 未処理例外に備えてるか? → window.onerror / unhandledrejection で最後の砦

よくあるミスと対策

❌ try/catchの範囲が広すぎて“どこで失敗したか”不明

→ ✅ 最小粒度のtry/catchに分割する


❌ catchの中でconsole.errorだけ

→ ✅ UI通知・ログ送信の両方を設計に組み込む


❌ どのエラーも“ただのError”として扱っている

→ ✅ カスタムエラーを定義し、意味のある分類を導入


結語

エラーとは設計の不備ではない。
それは**“設計が準備できていなかった現実”の現れ**である。

  • 例外は想定され
  • 通知は最小限に伝えられ
  • ログは未来のために残される

壊れたコードではなく、壊れても崩壊しないコードへ。
それがエラーハンドリング設計の使命である。

2
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?