概要
エラーハンドリングとは“例外が起きたときに止める”ことではない。
それは“壊れても崩壊しないための設計”であり、開発者とユーザーの双方に意味あるフィードバックを返すための構造的判断である。
本稿では、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”として扱っている
→ ✅ カスタムエラーを定義し、意味のある分類を導入
結語
エラーとは設計の不備ではない。
それは**“設計が準備できていなかった現実”の現れ**である。
- 例外は想定され
- 通知は最小限に伝えられ
- ログは未来のために残される
壊れたコードではなく、壊れても崩壊しないコードへ。
それがエラーハンドリング設計の使命である。