メインコンテンツへスキップ
レッスン 9 / 12推定時間: 35

エラー処理:失敗しても大丈夫な仕組み

完璧な自動化など存在しません。ネットワークは切れるし、サーバーは落ちるし、データは壊れることもあります。大切なのは、エラーが起きても安全に処理を続けられる仕組みを作ること。このレッスンでは、エラーに強い自動化の設計方法を学びます。

はじめに

これまでのレッスンで、自動化のさまざまな要素を学んできました。

でも、ちょっと考えてみてください。

現実の世界では:

  • インターネットが一時的に切れる
  • メールサーバーが応答しない
  • ファイルが見つからない
  • データの形式が想定と違う

エラーは必ず起きます。

今回は、そんなエラーと上手に付き合い、「失敗しても大丈夫」な自動化を作る方法を学びます。

エラーは日常茶飯事

日常生活のエラー処理

私たちは無意識にエラー処理をしています:

電車通勤の例

通常の計画:
7:30の電車に乗る → 8:00に会社到着

エラー処理:
もし電車が遅延したら
  → 会社に連絡
  → 別ルートを検索
  → タクシーも検討

料理の例

レシピ通りに作る

エラー処理:
もし材料が足りなければ
  → 代替品を使う
  → 量を調整する
  → 買い物に行く

ATMでお金を下ろす

通常の流れ:
カード挿入 → 暗証番号 → 金額指定 → 現金受取

エラー処理:
- カードが読めない → 再挿入を促す
- 暗証番号違い → 3回まで再入力可
- 残高不足 → エラーメッセージ
- 紙幣切れ → 別の金額を提案

エラー処理の基本原則

  • エラーは起きるものと想定する
  • エラーが起きても安全に処理を続ける
  • ユーザーに分かりやすく伝える
  • 回復の方法を用意する

エラーの種類を知る

1. 一時的なエラー(リトライで解決)

ネットワークエラー

症状:
- タイムアウト
- 接続拒否
- DNSエラー

対策:
- 数秒待って再試行
- 最大3-5回リトライ
- それでもダメなら諦める

リソース不足

症状:
- メモリ不足
- ディスク容量不足
- 同時接続数オーバー

対策:
- 少し待つ
- リソースを解放
- 処理を分割

2. データエラー(検証と修正)

形式エラー

期待:メールアドレス
実際:電話番号が入力された

対策:
- 入力チェック
- エラーメッセージ表示
- 正しい形式の例を表示

不正な値

期待:1-100の数値
実際:-50や200が入力された

対策:
- 範囲チェック
- デフォルト値を使用
- 修正を依頼

3. 権限・認証エラー

症状:
- ログイン失敗
- アクセス拒否
- トークン期限切れ

対策:
- 再認証を試みる
- 管理者に通知
- 代替アカウントを使用

4. 外部サービスエラー

症状:
- APIの仕様変更
- サービス停止
- レート制限

対策:
- エラーコードで判断
- 代替サービスを使用
- 処理を延期

エラー処理の基本戦略

戦略1:Try-Catch(エラーを捕まえる)

通常の処理を試みる(Try)
  ↓
もしエラーが発生したら(Catch)
  ↓
エラーに応じた対処

実例:ファイル処理

ファイルを開こうとする
  ↓
もしファイルが見つからなければ
  → エラーログに記録
  → デフォルトファイルを使用
  ↓
もし読み取り権限がなければ
  → 管理者に通知
  → 処理をスキップ

戦略2:事前チェック(予防)

処理を始める前に条件を確認
  ↓
条件を満たしていれば処理実行
  ↓
満たしていなければ別の対応

実例:メール送信前チェック

メール送信前に:
1. メールアドレスの形式確認
2. 添付ファイルのサイズ確認
3. 送信サーバーの稼働確認
  ↓
すべてOKなら送信
NGがあれば修正を促す

戦略3:フォールバック(代替手段)

プランA実行
  ↓失敗
プランB実行  
  ↓失敗
プランC実行
  ↓失敗
最終手段

実例:通知の送信

1. Slackで通知を試みる
   ↓ 失敗(Slackがダウン)
2. メールで通知を試みる
   ↓ 失敗(メールサーバーエラー)
3. SMSで通知を試みる
   ↓ 失敗
4. ログファイルに記録して後で確認

エラー処理の黄金律

  1. エラーを隠さない(必ずログに残す)
  2. エラーの内容を分かりやすく伝える
  3. 可能な限り処理を継続する
  4. データの整合性を保つ
  5. 回復方法を提供する

リトライ戦略

基本的なリトライ

最大試行回数 = 3
現在の試行回数 = 0

成功するまで繰り返す(最大3回):
    処理を実行
    もし成功したら
        ループを抜ける
    そうでなければ
        試行回数を増やす
        少し待つ

賢いリトライ(指数バックオフ)

待ち時間を徐々に増やす戦略:

1回目の失敗 → 1秒待つ
2回目の失敗 → 2秒待つ  
3回目の失敗 → 4秒待つ
4回目の失敗 → 8秒待つ
5回目の失敗 → 諦める

メリット:
- サーバーへの負荷を軽減
- 一時的な問題が解決する時間を与える

実践例:API呼び出しのリトライ

APIからデータ取得:

試行回数 = 0
待ち時間 = 1秒

5回まで繰り返す:
    APIを呼び出す
    
    もし成功(ステータス200)なら
        データを返して終了
    
    もしレート制限(ステータス429)なら
        指定された時間待つ
        続行
    
    もしサーバーエラー(ステータス500番台)なら
        待ち時間だけ待つ
        待ち時間を2倍にする
        続行
    
    もしクライアントエラー(ステータス400番台)なら
        即座に失敗(リトライしても無駄)

すべて失敗したら代替データを使用

エラー通知とログ

エラーレベルの分類

1. 情報(INFO)

内容:正常な処理の記録
例:「処理を開始しました」
対応:特になし

2. 警告(WARNING)

内容:想定内の軽微な問題
例:「在庫が残り10個です」
対応:注意して監視

3. エラー(ERROR)

内容:処理は続行するが問題あり
例:「メール送信に失敗、リトライします」
対応:原因調査が必要

4. 致命的(CRITICAL)

内容:処理が停止する重大な問題
例:「データベース接続不可」
対応:即座に対応が必要

効果的なエラーログ

悪い例

エラーが発生しました

良い例

[2024-01-20 14:30:25] ERROR: メール送信失敗
詳細:SMTPサーバー(mail.example.com)への接続タイムアウト
対象:customer@example.com
試行回数:3/3
次の動作:代替サーバーで再試行

通知の使い分け

エラーレベルによる通知先:

INFO → ログファイルのみ
WARNING → ログ + 日次レポート
ERROR → ログ + メール通知
CRITICAL → ログ + メール + SMS + 電話

実践的なエラー処理パターン

パターン1:トランザクション処理

銀行振込の例:

トランザクション開始
    ↓
try:
    1. 送金元の残高確認
    2. 送金元から引き落とし
    3. 送金先に入金
    4. 履歴を記録
    すべて成功 → コミット(確定)

catch(エラー発生):
    ロールバック(すべて元に戻す)
    エラーを記録
    ユーザーに通知

パターン2:部分的成功の処理

1000件のメール送信:

成功リスト = []
失敗リスト = []

各メールアドレスに対して:
    try:
        メール送信
        成功リストに追加
    catch:
        失敗リストに追加
        エラー詳細を記録

処理完了後:
- 成功:800件
- 失敗:200件
- 失敗分は後で再送信

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

外部サービス呼び出し:

エラー回数 = 0
しきい値 = 5

もしエラー回数 > しきい値なら
    → サービスを一時的に使用停止
    → 30分後に再開を試みる
    → 代替手段を使用

これにより:
- 壊れたサービスを呼び続けない
- システム全体への影響を防ぐ
- 自動的に回復を試みる

パターン4:デッドレターキュー

処理できないデータの扱い:

通常の処理キュー
    ↓
処理を試みる
    ↓ 失敗
3回リトライ
    ↓ それでも失敗
デッドレターキューへ移動
    ↓
後で人間が確認・対応

エラーからの自動回復

自己修復の仕組み

Webサーバー監視:

5分ごとにヘルスチェック
    ↓
もし応答なしなら:
    1. プロセスの再起動を試みる
    2. それでもダメならサーバー再起動
    3. それでもダメなら予備サーバーに切替
    4. 管理者に通知

データ整合性の維持

在庫管理システム:

注文処理でエラー発生
    ↓
不整合チェック:
- 注文データあり、在庫引き当てなし
    → 在庫を引き当て直す
- 在庫引き当てあり、注文データなし
    → 在庫を解放する
- 二重引き当て
    → 古い方を解放

エラーに強い設計のコツ

1. 冪等性(べきとうせい)を保つ

同じ処理を何度実行しても結果が同じになる設計:

❌ 悪い例:
残高 = 残高 + 1000円
(2回実行すると2000円増える)

✅ 良い例:
もし処理ID-123が未処理なら
    残高 = 残高 + 1000円
    処理ID-123を処理済みにする
(何度実行しても1000円しか増えない)

2. タイムアウトを設定

外部API呼び出し:
- 接続タイムアウト:5秒
- 読み取りタイムアウト:30秒
- 全体タイムアウト:60秒

これにより無限に待つことを防ぐ

3. 優雅な劣化(グレースフルデグラデーション)

商品推奨システム:

通常:AIによる高度な推奨
    ↓ AIサービスがダウン
代替1:過去の購買履歴から推奨
    ↓ 履歴データベースもダウン  
代替2:人気商品トップ10を表示
    ↓ それも無理なら
最終:「推奨商品は現在準備中」

今日のまとめ

エラー処理マスターの心得

  1. エラーは必ず起きると想定して設計
  2. エラーの種類に応じた適切な対処
  3. リトライ、フォールバック、ログを活用
  4. データの整合性を最優先に
  5. ユーザーへの影響を最小限に

次回予告

次のレッスンでは、「API連携の基礎:異なるサービスをつなぐ仕組み」を学びます。

  • APIとは何か
  • 異なるサービス間のデータ連携
  • 認証とセキュリティ
  • 実践的な連携パターン

エラー処理の知識と組み合わせれば、安定したサービス連携が実現できます!

チャレンジ問題

問題1:エラーの分類

以下のエラーを適切なレベル(INFO/WARNING/ERROR/CRITICAL)に分類してください:

  1. ユーザーがログインしました
  2. ディスク使用率が80%に達しました
  3. メール送信に失敗しましたが、リトライで成功
  4. データベースサーバーが応答しません
  5. 在庫が残り5個になりました
答えを見る
  1. INFO:正常な動作の記録
  2. WARNING:まだ大丈夫だが注意が必要
  3. ERROR:一時的な失敗(回復済み)
  4. CRITICAL:サービスが停止する重大な問題
  5. WARNING:しきい値に近づいている

問題2:リトライ戦略の設計

「外部APIからデータを取得する」処理で、適切なリトライ戦略を設計してください。

要件:

  • ネットワークエラーは再試行する価値あり
  • 認証エラーは再試行しても無駄
  • サーバーが混雑している場合は時間をおく
設計例を見る
最大リトライ回数 = 3
基本待機時間 = 2秒

APIを呼び出す
    ↓
レスポンスを確認:

もし成功(200番台)なら
    → データを返す

もし認証エラー(401, 403)なら
    → 即座に失敗(リトライしない)
    → 「認証情報を確認してください」

もしレート制限(429)なら
    → ヘッダーから待機時間を取得
    → 指定時間待機してリトライ

もしサーバーエラー(500番台)なら
    → 待機時間 × 試行回数 だけ待つ
    → リトライ(最大3回)

もしタイムアウトなら
    → 2秒待ってリトライ(最大3回)

すべて失敗したら
    → キャッシュデータを使用
    → 「最新データの取得に失敗しました」

問題3:エラーに強い設計

「100個のファイルを処理して、結果をデータベースに保存する」システムを、エラーに強く設計してください。

考慮点:

  • 一部のファイルが壊れている可能性
  • データベースが一時的に使えない可能性
  • 処理の途中で中断される可能性
設計例を見る
設計のポイント:

1. 処理状態の管理
   - 各ファイルに処理状態を記録
   - 未処理/処理中/完了/エラー

2. 部分的な成功を許容
   成功数 = 0
   失敗リスト = []
   
   各ファイルに対して:
       もし処理済みならスキップ
       
       状態を「処理中」に更新
       try:
           ファイル処理
           DB保存(リトライ付き)
           状態を「完了」に更新
           成功数++
       catch:
           状態を「エラー」に更新
           失敗リストに追加
           エラー詳細を記録

3. 中断からの再開
   - 処理開始時に「処理中」のものを「未処理」に戻す
   - これにより中断されても続きから再開可能

4. データベースエラー対策
   - 接続プールを使用
   - トランザクション単位を小さく
   - 一時ファイルに保存し、後でDB投入

5. 最終レポート
   - 成功: 95個
   - 失敗: 5個(詳細付き)
   - 処理時間: 10分
   - 失敗分の再処理方法を提示

エラー処理は地味ですが、自動化の品質を大きく左右する重要な要素です。「転ばぬ先の杖」として、しっかり設計しましょう!

さらに学習を続けるには

素晴らしい学習ペースです!次のレッスンに進むには、無料会員登録をお願いします。無料会員では各コース3レッスンまで学習できます。

無料で続きを学ぶ

各コース3レッスンまで学習可能

学習進捗の自動保存

コース修了証明書の発行