はじめに
システム開発において、エラーは必ず発生します。重要なのは、エラーをどう扱うかです。AI開発では、エラーハンドリングの設計が特に重要になります。
エラーハンドリングの目的
1. ユーザー体験の維持
✗ 悪い例:「Error: SQLITE_CONSTRAINT」
◯ 良い例:「入力内容を確認してください。メールアドレスはすでに登録されています。」
2. デバッグの容易化
// ログに記録する情報
- エラー発生日時
- エラー種別
- 発生箇所
- リクエスト内容
- スタックトレース(内部用)
3. システムの安定性
エラーが発生しても、システム全体が停止しないようにします。
エラーの分類
【予測可能なエラー】
- 入力値のバリデーションエラー
- 認証エラー
- リソースが見つからない(404)
- 権限エラー(403)
→ 適切なメッセージでユーザーに通知
【予測不能なエラー】
- データベース接続エラー
- 外部API障害
- メモリ不足
- プログラムのバグ
→ 汎用メッセージを表示し、詳細はログに記録
エラーハンドリングの設計パターン
パターン1:エラーコードの統一
const ERROR_CODES = {
// 認証系
AUTH_REQUIRED: 'AUTH_REQUIRED',
AUTH_INVALID_TOKEN: 'AUTH_INVALID_TOKEN',
// バリデーション系
VALIDATION_REQUIRED: 'VALIDATION_REQUIRED',
VALIDATION_FORMAT: 'VALIDATION_FORMAT',
// システム系
SYSTEM_ERROR: 'SYSTEM_ERROR',
DATABASE_ERROR: 'DATABASE_ERROR'
};
パターン2:レスポンス形式の統一
// 成功レスポンス
{
"success": true,
"data": { ... }
}
// エラーレスポンス
{
"success": false,
"error": {
"code": "VALIDATION_REQUIRED",
"message": "メールアドレスは必須です",
"field": "email"
}
}
セキュリティ上の注意
// ❌ 危険:詳細情報を外部に露出
{
"error": "Error: SQLITE_CONSTRAINT: UNIQUE constraint failed..."
}
// ✅ 安全:汎用メッセージ
{
"error": {
"code": "RESOURCE_CONFLICT",
"message": "このメールアドレスはすでに登録されています"
}
}
仕様書への記載
## エラーハンドリング仕様
### 入力値エラー
- 必須項目が未入力の場合、フィールド単位でエラーメッセージを表示
- フォーマット不正の場合、正しい形式を案内
### 認証エラー
- 未ログイン:ログイン画面へリダイレクト
- トークン期限切れ:自動リフレッシュを試行
### システムエラー
- ユーザーには汎用メッセージを表示
- 詳細はサーバーログに記録
まとめ
エラーハンドリングの設計は、以下の原則に従いましょう:
- ユーザーには分かりやすく - 専門用語を避けた説明
- 開発者には詳細に - ログで十分な情報を記録
- 形式を統一 - エラーコード、レスポンス形式
- 集約して管理 - 共通ハンドラーで一元管理
- セキュリティに注意 - 内部情報の漏洩防止
次回:「ドキュメント駆動開発の実践」