はじめに
これまでのレッスンで、自動化のさまざまな要素を学んできました。
でも、ちょっと考えてみてください。
現実の世界では:
- インターネットが一時的に切れる
- メールサーバーが応答しない
- ファイルが見つからない
- データの形式が想定と違う
エラーは必ず起きます。
今回は、そんなエラーと上手に付き合い、「失敗しても大丈夫」な自動化を作る方法を学びます。
エラーは日常茶飯事
日常生活のエラー処理
私たちは無意識にエラー処理をしています:
電車通勤の例
通常の計画:
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. ログファイルに記録して後で確認
エラー処理の黄金律
- エラーを隠さない(必ずログに残す)
- エラーの内容を分かりやすく伝える
- 可能な限り処理を継続する
- データの整合性を保つ
- 回復方法を提供する
リトライ戦略
基本的なリトライ
最大試行回数 = 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を表示
↓ それも無理なら
最終:「推奨商品は現在準備中」
今日のまとめ
エラー処理マスターの心得
- エラーは必ず起きると想定して設計
- エラーの種類に応じた適切な対処
- リトライ、フォールバック、ログを活用
- データの整合性を最優先に
- ユーザーへの影響を最小限に
次回予告
次のレッスンでは、「API連携の基礎:異なるサービスをつなぐ仕組み」を学びます。
- APIとは何か
- 異なるサービス間のデータ連携
- 認証とセキュリティ
- 実践的な連携パターン
エラー処理の知識と組み合わせれば、安定したサービス連携が実現できます!
チャレンジ問題
問題1:エラーの分類
以下のエラーを適切なレベル(INFO/WARNING/ERROR/CRITICAL)に分類してください:
- ユーザーがログインしました
- ディスク使用率が80%に達しました
- メール送信に失敗しましたが、リトライで成功
- データベースサーバーが応答しません
- 在庫が残り5個になりました
答えを見る
- INFO:正常な動作の記録
- WARNING:まだ大丈夫だが注意が必要
- ERROR:一時的な失敗(回復済み)
- CRITICAL:サービスが停止する重大な問題
- 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分
- 失敗分の再処理方法を提示
エラー処理は地味ですが、自動化の品質を大きく左右する重要な要素です。「転ばぬ先の杖」として、しっかり設計しましょう!