概要
例外処理は「エラーを捕まえるため」だけにあるのではない。
それは**“失敗する可能性を前提とした制御構造”であり、アプリケーションの堅牢性を支える設計要素**である。
JavaScriptの try-catch
はシンプルだが、適用範囲や粒度を誤ると、本来の責務が不明瞭になり、デバッグ困難なコードを生む。
本稿では、例外設計の粒度、責任の分離、伝播戦略、ドメインとUI層での分担を含め、エラーハンドリングを構造的に整理する。
1. try-catch の構文と基本原則
try {
const data = JSON.parse(jsonStr);
} catch (err) {
console.error('JSON parsing failed:', err);
}
- ✅ 失敗が「予想される」コードブロックにのみ適用
- ❌ すべての処理を try に包むのはアンチパターン
2. 層ごとのエラーハンドリング戦略
❖ ドメイン層(ビジネスロジック)
- ✅ 原因に応じた具体的な例外クラスを throw
- ✅ 曖昧な
throw 'error'
は避ける。Errorオブジェクトを必ず使用
class ValidationError extends Error {}
function validate(user) {
if (!user.email) throw new ValidationError('Email is required');
}
❖ アプリケーション層(呼び出し元)
- ✅ try-catch で受け止め、ログやUI通知に変換
- ✅ 原則として「処理と通知の責務を分離」する
try {
validate(input);
} catch (err) {
if (err instanceof ValidationError) {
showToast(err.message);
} else {
throw err; // 上位に再スロー
}
}
3. 非同期処理での try-catch
async function fetchData() {
try {
const res = await fetch('/api/data');
const json = await res.json();
return json;
} catch (err) {
console.error('Fetch failed:', err);
throw err;
}
}
- ✅ async/await でも通常の try-catch を適用
- ❌
.catch()
のみで副作用的に扱うのは構造的に脆い
4. 共通エラーハンドラの抽象化
function handleError(err: unknown) {
if (err instanceof NetworkError) {
logNetwork(err);
} else if (err instanceof ValidationError) {
notifyUser(err.message);
} else {
reportCritical(err);
}
}
- ✅ エラーごとに分岐を整理し、設計として定義
- ✅ 呼び出し元では
handleError()
という責務のみに集中できる
5. 設計粒度の指針:どこで try-catch を置くべきか
処理範囲 | 例外処理設計 |
---|---|
小さすぎる | try が乱立し、構造が煩雑になる |
大きすぎる | 何が失敗したか分からなくなる |
責務単位で配置する | ✅ ロジック単位ごとに try を設ける |
設計判断フロー
① 例外は予期された失敗か? → ifによるバリデーションが適切では?
② どの層で try-catch を置くべきか?(UI/ドメイン/インフラ)
③ エラー種別は Errorクラスで定義されているか?
④ 処理と通知の責務は分離されているか?
⑤ エラーが再スロー or 回収で明示的に扱われているか?
よくあるミスと対策
❌ catch ですべてを握りつぶしてログだけ吐く
→ ✅ 処理責任に応じて通知 / 再スローの判断を明示
❌ throw 'string'
のような雑な例外投げ
→ ✅ 必ず new Error()
or カスタムエラーを使用
❌ 非同期関数内で try-catch を使わず .catch()
に処理を書きすぎる
→ ✅ await
+ try-catch
で構造を明確化
結語
例外処理は「失敗を捕まえるもの」ではない。
それは**“期待される制御フローの逸脱を、設計的に扱うための構造要素”**である。
- try-catch の配置には戦略が必要
- 失敗は「例外」ではなく「分岐条件」として設計すべき場合もある
- 責務の分離こそが、例外処理を「デザイン」に変える鍵
JavaScriptにおけるエラーハンドリングとは、
“失敗の発生を想定し、制御下に置くための設計戦略である。”