エラーハンドリング設計 – 例外処理とリカバリ戦略の体系化

「本番環境でエラーが発生したとき、どうすればいいのか分からない…」

そんな不安を抱えていませんか?

20年のプログラマ経験があるあなたなら、エラーが発生したときに「とりあえずtry-catchで囲む」という対処をしてきたはずです。しかし、それだけでは本当の意味でのエラーハンドリングにはなりません。

「ユーザーにどんなメッセージを表示すべきか?」「ログには何を記録すべきか?」「システムはどう復旧させるべきか?」——これらの判断ができるかどうかが、上流工程のエンジニアとコーディングだけを担当するプログラマの決定的な違いです。

45歳のあなたが目指す「要件定義からシステム設計まで担当できるエンジニア」になるには、エラーハンドリングを体系的に設計する力が不可欠です。なぜなら、システムの信頼性と保守性を左右する重要な設計要素だからです。

この記事では、1日30分×2週間の学習で、実務で通用するエラーハンドリング設計力を身につけるロードマップをお伝えします。完璧を目指す必要はありません。まずは「エラーを適切に分類し、対処方針を決められる」レベルを目指しましょう。


目次

第1章:なぜエラーハンドリング設計が上流工程への鍵なのか?

結論

エラーハンドリング設計は、システムアーキテクトやITコンサルタントに必須のスキルです。

理由

システム設計において、正常系の処理を考えるのは比較的簡単です。しかし、異常系の処理をどう設計するかが、システムの品質と信頼性を決定します。

上流工程のエンジニアは、「このエラーはユーザーに見せるべきか?」「リトライすべきか?」「システムを停止すべきか?」といった判断を、設計段階で明確にする必要があります。

特に、クラウド時代のマイクロサービスアーキテクチャでは、ネットワークエラーや外部API障害など、予期しないエラーが日常的に発生します。これらを適切にハンドリングできる設計力が、年収650万円以上のポジションでは必須要件になっています。

具体例

46歳でSIerからWeb系企業のシステムアーキテクトに転職したHさんは、こう語ります。

「面接で『決済API障害時のエラーハンドリングをどう設計しますか?』と聞かれました。『リトライロジック、サーキットブレーカーパターン、ユーザーへの適切なエラーメッセージ、ログ設計、運用チームへの通知』を体系的に説明したところ、『設計レベルで考えられる人材を探していた』と即日内定。年収は500万円から720万円になりました」

まとめ

エラーハンドリング設計は、単なるtry-catch の配置ではなく、システム全体の信頼性を担保する戦略的な設計活動です。この力を身につけることで、上流工程への扉が開かれます。


第2章:エラーの4つの分類を理解する

結論

すべてのエラーは、ビジネスエラー、バリデーションエラー、システムエラー、外部エラーの4つに分類できます。

理由

エラーハンドリングの第一歩は、エラーを適切に分類することです。分類が明確になれば、それぞれのエラーに対する対処方針が自然と決まります。

この4分類は、多くのエンタープライズシステムで採用されている業界標準です。上流工程のエンジニアは、この分類を使って設計書を書き、開発チームに指示を出します。

具体例

1. ビジネスエラー

定義: 業務ルールに違反した場合のエラー
: 「在庫が不足しています」「予算を超過しています」
対処方針: ユーザーに分かりやすいメッセージを表示し、修正を促す
リトライ: 不要(ユーザーの入力修正が必要)

if (stock < orderQuantity) {
  throw new BusinessError('在庫が不足しています。現在の在庫数: ' + stock);
}

2. バリデーションエラー

定義: 入力値の形式や範囲が不正な場合のエラー
: 「メールアドレスの形式が正しくありません」「必須項目が未入力です」
対処方針: 入力フォームにエラーメッセージを表示
リトライ: 不要(ユーザーの再入力が必要)

3. システムエラー

定義: システム内部の問題で発生するエラー
: データベース接続エラー、メモリ不足、ファイル書き込み失敗
対処方針: ユーザーには「システムエラーが発生しました」と表示、詳細ログを記録、運用チームに通知
リトライ: 状況による(一時的な障害なら自動リトライ)

4. 外部エラー

定義: 外部APIやサービスの障害で発生するエラー
: 決済APIタイムアウト、天気予報APIの503エラー
対処方針: リトライ、フォールバック、サーキットブレーカー
リトライ: 推奨(ネットワーク障害は一時的なことが多い)

まとめ

エラーを4つに分類することで、「このエラーにはどう対処すべきか」が明確になります。この分類を習得すれば、設計書に「エラー分類ごとの対処方針」を記載できるようになります。

関連記事
テスト駆動開発(TDD)の始め方 – ユニットテストから統合テストまでの実践
エラーハンドリングのテストコードを書く力を身につけましょう。


第3章:例外処理の3つの基本パターン

結論

例外処理には、キャッチ&ログ、キャッチ&リスロー、キャッチ&リカバリの3つの基本パターンがあります。

理由

多くのプログラマが陥る罠は、「とりあえず全部キャッチする」ことです。しかし、すべての例外を同じように扱うと、システムの異常を見逃したり、不要な処理が増えたりします。

上流工程のエンジニアは、「この例外はどのレイヤーで処理すべきか」を設計段階で決定します。この判断ができることが、設計力の証明になります。

具体例

パターン1: キャッチ&ログ(Catch & Log)

使用場面: エラー情報を記録したいが、処理は続行できる場合
: 外部ログサービスへの送信失敗

try {
  sendToExternalLogger(logData);
} catch (error) {
  console.error('外部ログ送信失敗:', error);
  // 処理は続行する
}

パターン2: キャッチ&リスロー(Catch & Rethrow)

使用場面: エラー情報を追加してから、上位レイヤーに再スローする場合
: データベースエラーに業務コンテキストを追加

try {
  const user = await database.getUser(userId);
} catch (error) {
  throw new Error('ユーザー取得失敗: userId=' + userId, { cause: error });
}

パターン3: キャッチ&リカバリ(Catch & Recover)

使用場面: エラーをキャッチし、代替処理で復旧できる場合
: キャッシュ取得失敗時にデータベースから取得

async function getUserData(userId) {
  try {
    return await cache.get(userId);
  } catch (error) {
    console.warn('キャッシュ取得失敗、DBから取得します');
    return await database.getUser(userId);
  }
}

学習ステップ(1日30分×3日間)

  • 1日目: 自分の過去のコードで、どのパターンを使っているか確認
  • 2日目: 各パターンを使った簡単なサンプルコードを書く
  • 3日目: 実務のコードに適切なパターンを適用する

まとめ

3つのパターンを理解すれば、「このエラーはここでキャッチすべきか、上に投げるべきか」という設計判断ができるようになります。

【おすすめ学習教材】
Udemy – エラーハンドリングとロギングの実践
実務で使えるエラーハンドリングのパターンを体系的に学べます(セール時1,200円〜)


第4章:リトライ戦略とサーキットブレーカーパターン

結論

外部APIやネットワーク障害には、リトライロジックサーキットブレーカーパターンを組み合わせて対処します。

理由

クラウド時代のシステムでは、ネットワーク障害は「いつか起こる」ものです。しかし、無限にリトライすると、システム全体が停止してしまいます。

適切なリトライ戦略を設計することで、一時的な障害を乗り越え、システムの可用性を高められます。これが、クラウドエンジニアやソリューションアーキテクトに求められる設計力です。

具体例

リトライロジックの基本

指数バックオフ(Exponential Backoff)
リトライ間隔を指数的に延ばす戦略

async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fetch(url);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      const waitTime = Math.pow(2, i) * 1000; // 1秒、2秒、4秒
      console.log(`リトライ ${i + 1}回目、${waitTime}ms後に再試行`);
      await sleep(waitTime);
    }
  }
}

サーキットブレーカーパターン

定義: 障害が続く場合、一定期間リクエストを遮断し、システムを保護する
3つの状態:

  1. Closed(正常): リクエストを通す
  2. Open(遮断): エラーが閾値を超えたら、リクエストを即座に失敗させる
  3. Half-Open(半開): 一定時間後、試験的にリクエストを通す

実装例(簡易版)

class CircuitBreaker {
  constructor(threshold = 5, timeout = 60000) {
    this.failureCount = 0;
    this.threshold = threshold;
    this.state = 'CLOSED';
    this.nextAttempt = Date.now();
  }

  async execute(fn) {
    if (this.state === 'OPEN') {
      if (Date.now() < this.nextAttempt) {
        throw new Error('サーキットブレーカーがOPEN状態です');
      }
      this.state = 'HALF_OPEN';
    }

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  onSuccess() {
    this.failureCount = 0;
    this.state = 'CLOSED';
  }

  onFailure() {
    this.failureCount++;
    if (this.failureCount >= this.threshold) {
      this.state = 'OPEN';
      this.nextAttempt = Date.now() + 60000; // 60秒後に再試行
    }
  }
}

まとめ

リトライとサーキットブレーカーを組み合わせることで、一時的な障害に強く、かつシステム全体を守る設計ができます。この知識は、面接で「可用性の高いシステムをどう設計しますか?」と聞かれたときの強力な武器になります。

関連記事
セキュリティ基礎とOWASP Top 10対策 – Webアプリケーションの脆弱性対策入門
エラーメッセージから情報が漏れないようにするセキュリティ対策も重要です。


第5章:ユーザーへのエラーメッセージ設計

結論

エラーメッセージは、ユーザー向け開発者向けの2つを明確に分けて設計します。

理由

多くのシステムで見かける最悪のエラーメッセージは、「NullPointerException at line 342」のような技術的な内容をそのままユーザーに見せることです。

ユーザーが知りたいのは、「何が起きたのか」「どうすれば解決できるのか」であり、スタックトレースではありません。

一方、開発者や運用チームには、詳細なエラー情報が必要です。この両者を分けて設計することが、UX(ユーザー体験)と保守性の両立につながります。

具体例

良いエラーメッセージの3要素

  1. 何が起きたか(事実)
  2. なぜ起きたか(原因)
  3. どうすればいいか(対処法)

悪い例

エラーが発生しました。

良い例

在庫が不足しているため、注文を完了できませんでした。
現在の在庫数: 5個
ご注文数を5個以下に変更してください。

エラーメッセージの設計テンプレート

エラー分類ユーザー向けメッセージ開発者向けログ
ビジネスエラー「在庫が不足しています」BusinessError: stock=5, order=10, productId=ABC123
バリデーションエラー「メールアドレスの形式が正しくありません」ValidationError: invalid email format, input=test@
システムエラー「システムエラーが発生しました。しばらく待ってから再度お試しください」DatabaseError: connection timeout after 30s, host=db.example.com
外部エラー「外部サービスが一時的に利用できません。しばらく待ってから再度お試しください」ExternalAPIError: payment API returned 503, endpoint=/api/charge

学習課題(1日30分×2日間)

  • 1日目: 自分が使っているWebサービスで、良いエラーメッセージと悪いエラーメッセージを5つずつ収集する
  • 2日目: 過去に自分が書いたエラーメッセージを、3要素を満たすように書き直す

まとめ

エラーメッセージ設計は、システムのUXを大きく左右します。ユーザーに優しく、開発者に詳細な情報を提供するメッセージを設計できることが、上流工程のエンジニアの価値です。

関連記事
基本設計(外部設計)の全体像 – 画面・帳票・IF設計の進め方
画面設計と連動したエラーメッセージ設計を学べます。


第6章:ログ設計とエラー監視の実践

結論

エラーハンドリングの最終目的は、障害の早期発見と迅速な復旧です。そのためのログ設計が不可欠です。

理由

エラーをキャッチしても、適切なログを残さなければ、障害の原因を特定できません。特に本番環境では、ユーザーがどんな操作をしたときにエラーが起きたのかを再現することは困難です。

上流工程のエンジニアは、「どのレベルのエラーを、どこに、どんな形式でログ出力するか」を設計します。この設計が、システムの保守性と運用コストを決定します。

具体例

ログレベルの5段階

  1. ERROR: 即座に対応が必要な障害
  2. WARN: 異常だが、システムは継続可能
  3. INFO: 重要な業務イベント(ログイン、注文完了など)
  4. DEBUG: 開発時のデバッグ情報
  5. TRACE: 詳細なトレース情報

エラーログに含めるべき情報

{
  "timestamp": "2026-01-25T10:30:45Z",
  "level": "ERROR",
  "errorType": "DatabaseError",
  "message": "データベース接続タイムアウト",
  "userId": "user_12345",
  "requestId": "req_abc789",
  "endpoint": "/api/orders",
  "stackTrace": "...",
  "context": {
    "orderId": "order_999",
    "paymentMethod": "credit_card"
  }
}

エラー監視ツールの活用

Sentry: リアルタイムエラー監視とアラート通知
特徴: エラーの発生頻度、影響範囲、スタックトレースを可視化

導入例

import * as Sentry from "@sentry/node";

Sentry.init({ dsn: "your-dsn-here" });

try {
  processOrder(orderId);
} catch (error) {
  Sentry.captureException(error, {
    tags: { orderId: orderId },
    user: { id: userId }
  });
  throw error;
}

まとめ

ログ設計とエラー監視は、システムの運用品質を左右します。適切なログを設計できることで、「障害対応が早い、信頼できるエンジニア」という評価につながります。

【おすすめツール】
Sentry
エラー監視のデファクトスタンダード。無料プランでも十分使えます。

関連記事
詳細設計(内部設計)の進め方 – クラス設計からモジュール分割まで
クラス設計レベルでのエラーハンドリング実装を学べます。


第7章:実践プロジェクト – エラーハンドリングを組み込む

結論

理論を学んだら、実際のプロジェクトでエラーハンドリングを実装してみましょう。

理由

面接で「エラーハンドリング設計ができます」と言っても、実装例がなければ説得力がありません。GitHubに公開できるプロジェクトを作ることで、あなたのスキルを証明できます。

具体例

プロジェクト例: 天気予報アプリにエラーハンドリングを追加

STEP1: エラー分類の実装(所要時間: 2時間)

// カスタムエラークラスの定義
class BusinessError extends Error {
  constructor(message) {
    super(message);
    this.name = 'BusinessError';
  }
}

class ExternalAPIError extends Error {
  constructor(message, cause) {
    super(message);
    this.name = 'ExternalAPIError';
    this.cause = cause;
  }
}

STEP2: リトライロジックの実装(所要時間: 2時間)

async function fetchWeatherWithRetry(city) {
  const maxRetries = 3;
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(`https://api.weather.com/${city}`);
      if (!response.ok) throw new Error('API error');
      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) {
        throw new ExternalAPIError('天気情報の取得に失敗しました', error);
      }
      await sleep(Math.pow(2, i) * 1000);
    }
  }
}

STEP3: ユーザー向けエラーメッセージ表示(所要時間: 1時間)

try {
  const weather = await fetchWeatherWithRetry(city);
  displayWeather(weather);
} catch (error) {
  if (error instanceof ExternalAPIError) {
    showError('天気情報を取得できませんでした。しばらく待ってから再度お試しください。');
  } else {
    showError('予期しないエラーが発生しました。');
  }
  console.error('詳細:', error);
}

STEP4: GitHubで公開(所要時間: 30分)

READMEに以下を記載:

  • 実装したエラーハンドリングの種類
  • リトライ戦略の説明
  • エラーログの設計方針

まとめ

小さなプロジェクトでも、エラーハンドリングを体系的に実装した経験があれば、面接で「実務レベル」として評価されます。1週間あれば完成できるので、今週末から始めましょう。

【開発環境におすすめ】
GitHub Copilot
エラーハンドリングのコードをAIが補完してくれるので、学習効率が3倍になります(月額10ドル、60日間無料)


第8章:設計書へのエラーハンドリング仕様の記載

結論

上流工程のエンジニアは、設計書にエラーハンドリングの方針を明記します。

理由

開発チームがバラバラにエラー処理を実装すると、システム全体の一貫性が失われます。設計書で「どのエラーを、どこで、どう処理するか」を明確にすることが、上流工程の役割です。

具体例

設計書への記載例

エラーハンドリング設計方針

1. エラー分類と対処方針

エラー分類対処方針リトライユーザー通知ログレベル
ビジネスエラーユーザーに修正を促すなしあり(詳細)INFO
バリデーションエラー入力フォームにエラー表示なしあり(項目単位)WARN
システムエラー運用チームに通知状況によるあり(簡潔)ERROR
外部APIエラーリトライ→サーキットブレーカー3回まであり(簡潔)ERROR

2. リトライ戦略

  • 最大リトライ回数: 3回
  • リトライ間隔: 指数バックオフ(1秒、2秒、4秒)
  • リトライ対象: 外部APIエラー、一時的なネットワークエラー
  • リトライ対象外: バリデーションエラー、ビジネスエラー

3. エラーログ出力仕様

  • 出力先: CloudWatch Logs(AWS)
  • 出力形式: JSON
  • 必須フィールド: timestamp, level, errorType, message, userId, requestId

4. エラー監視・通知

  • 監視ツール: Sentry
  • 通知条件: ERRORレベルのログが10分間に5回以上発生
  • 通知先: Slack #alerts チャンネル

まとめ

設計書にエラーハンドリング仕様を記載することで、開発チーム全体が統一された方針でエラー処理を実装できます。この設計書が書けることが、システムアーキテクトへの第一歩です。

関連記事
基本設計書のドキュメント構成 – 保守性の高い設計書作成術
設計書の書き方を体系的に学べます。


第9章:面接でのエラーハンドリング設計のアピール方法

結論

面接では、具体的なプロジェクト経験を交えてエラーハンドリング設計を説明しましょう。

理由

「エラーハンドリングができます」だけでは、面接官には伝わりません。「どんなエラーを、どう分類し、どう設計したか」を具体的に説明できることが、上流工程の求人で評価されます。

具体例

面接での回答例

質問: 「外部API障害時のエラーハンドリングをどう設計しますか?」

回答:

「まず、エラーを4つに分類します。外部APIエラーは『外部エラー』に該当し、リトライとサーキットブレーカーで対処します。

具体的には、指数バックオフで最大3回リトライし、それでも失敗する場合はサーキットブレーカーをOPEN状態にして、60秒間リクエストを遮断します。

ユーザーには『外部サービスが一時的に利用できません。しばらく待ってから再度お試しください』と表示し、開発者向けには『ExternalAPIError: payment API returned 503, endpoint=/api/charge, retry=3/3』というログを出力します。

また、ERRORレベルのログが10分間に5回以上発生した場合、Slackで運用チームに通知する設計にします。

この設計により、一時的な障害には自動復旧し、長時間の障害には迅速に対応できる体制を構築できます」

GitHubリポジトリの活用

「実際に、こちらのGitHubリポジトリで天気予報アプリを作成しました。READMEに、エラーハンドリングの設計方針とコード例を記載しています。ぜひご覧ください」

まとめ

面接では、理論だけでなく実装経験を示すことが重要です。GitHubに公開したプロジェクトがあれば、「実務レベル」として高く評価されます。

関連記事
レガシーコードのリファクタリング戦略 – 技術的負債を計画的に解消する
既存システムのエラーハンドリングを改善する方法を学べます

第10章:今日から始める3つの行動

結論

この記事を読んだ「今」が、エラーハンドリング設計を学び始める最良のタイミングです。

理由

エラーハンドリング設計は、2週間の学習で実務レベルに到達できます。完璧を目指す必要はありません。まずは、以下の3つの小さな行動から始めてください。

具体例

STEP1: Udemy講座を1つ購入する(所要時間: 10分)

「いつか買おう」ではなく、今すぐ購入してください。セールなら1,200円程度です。購入した瞬間、あなたの学習は「本気」に変わります。

おすすめ: Udemy – エラーハンドリングとロギングの実践

STEP2: 自分の過去のコードでエラー処理を見直す(所要時間: 30分)

今日中に、過去に書いたコードを1つ開き、エラー処理を確認してください。「このエラーは、どの分類に該当するか?」「リトライすべきか?」を考えるだけで、設計視点が身につきます。

STEP3: 小さなプロジェクトでエラーハンドリングを実装する(所要時間: 1週間)

今週末から、天気予報アプリやToDoアプリに、リトライロジックとエラーメッセージ設計を追加してみましょう。完成したらGitHubに公開し、READMEに設計方針を記載してください。

3つの行動を実行した人の変化

44歳プログラマ・Kさん(1週間で3つの行動を完了):

「記事を読んで、『エラーハンドリングは設計の一部』という視点が欠けていたことに気づきました。その日のうちにUdemyで講座を購入し、週末にToDoアプリにエラーハンドリングを追加。GitHubで公開したところ、面接で『設計レベルで考えられる人材』と評価され、内定をもらいました。年収は480万円から680万円になりました」

まとめ

この3つのステップは、1週間で完了できます。つまり、来週のあなたは「エラーハンドリング設計ができるエンジニア」として、上流工程への道を歩み始めているのです。

【今すぐ始める学習セット】

関連記事
ドメイン駆動設計(DDD)入門 – ビジネスロジックを正しくモデリングする
エラーハンドリングをドメインモデルに組み込む設計を学べます。


まとめ

エラーハンドリング設計習得ロードマップの全体像

第1週: エラー分類と基本パターンの理解
→ ビジネスエラー、バリデーションエラー、システムエラー、外部エラーの4分類を習得
→ キャッチ&ログ、キャッチ&リスロー、キャッチ&リカバリの3パターンを理解

第2週: リトライとサーキットブレーカーの実装
→ 指数バックオフによるリトライロジックを実装
→ サーキットブレーカーパターンでシステムを保護

第3週: ログ設計とエラーメッセージ設計
→ ユーザー向けと開発者向けのエラーメッセージを分離
→ 適切なログレベルとログ出力内容を設計

第4週: 実践プロジェクトとGitHub公開
→ 天気予報アプリやToDoアプリにエラーハンドリングを実装
→ 設計方針をREADMEに記載してGitHubで公開

1ヶ月後: 転職活動で武器にする
→ 面接で具体的なプロジェクト経験を説明
→ 上流工程の求人に自信を持って応募

最後に: 45歳のあなたへ

「エラーハンドリングなんて、地味なスキル」——そう思っていませんか?

しかし、システムの信頼性と保守性を決定する、最も重要な設計要素の1つです。そして、多くのプログラマが体系的に学んでいないからこそ、あなたがこのスキルを身につければ、大きな差別化になります。

行動しなければ、何も変わりません。

でも、今日Udemyで講座を1つ買い、今夜30分だけ過去のコードを見直せば、明日のあなたは「昨日より設計力が高いエンジニア」になっています。

1ヶ月後、あなたは「エラーハンドリング設計ができる上流エンジニア」として、年収650万円以上のオファーを手にしているはずです。

その第一歩を、今日、踏み出しましょう。

【今日から始める学習セット – 最後のご案内】

  • Udemy講座: セール中なら1,200円〜。エラーハンドリングから上流スキルまで幅広くカバー
  • Kindle Unlimited: 30日間無料体験。通勤時間が学習時間に変わります
  • GitHub Copilot: AIペアプログラミング。学習効率が劇的に向上します

関連記事
システム設計面接対策とケーススタディ – スケーラビリティを考慮した設計力
面接でのシステム設計の説明方法を学べます。

詳細設計レビューの実践 – コードレビュー前の設計品質確保
エラーハンドリング設計のレビュー観点を学べます。


Todd

あなたの成功を、心から応援しています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次