🚨 エラーハンドリングデモ
カスタム例外クラスと ExceptionHandlingMiddleware の動作を体験できるデモ
📚 例外クラスの設計
このアプリでは ApplicationException(抽象基底クラス)を継承した4種類のカスタム例外を定義しています。
Exception(.NET標準)
└── ApplicationException(抽象・独自定義)
├── ValidationException → 400
├── NotFoundException → 404
├── BusinessRuleException → 400
└── InfrastructureException→ 500
| 例外クラス | HTTP | 用途 |
|---|---|---|
ValidationException |
400 | 入力値エラー |
NotFoundException |
404 | リソース未存在 |
BusinessRuleException |
400 | ビジネスルール違反 |
InfrastructureException |
500 | DB・外部API障害 |
Exception(その他) |
500 | 予期しないエラー |
🔥 例外を意図的に発火してみる
ボタンを押すと API エンドポイントを呼び出し、ExceptionHandlingMiddleware が例外をキャッチして JSON レスポンスに変換します。
ValidationException
入力値が不正な場合。複数フィールドのエラーをまとめて返す。
NotFoundException
指定IDのリソースが存在しない場合。resourceType・resourceId を返す。
BusinessRuleException
技術的には正常でもビジネスルール違反の場合。ruleName を返す。
InfrastructureException
DB・外部API障害など、システム起因のエラー。service名を返す。
予期しない例外
NullReferenceException 等のランタイムエラー。INTERNAL_ERROR を返す。
💻 レスポンス
← ボタンを押すとここにレスポンスが表示されます
⚙️ ExceptionHandlingMiddleware の仕組み
例外ハンドリングを Controller ごとに書く代わりに、Middleware で一括管理しています。
❌ Bad: Controller 個別に try-catch
// 全 Controller に同じコードが重複する
public async Task<IActionResult> GetUser(int id)
{
try {
var user = await _service.GetUser(id);
return Ok(user);
}
catch (NotFoundException ex) {
return NotFound(new { error = ex.Message });
}
catch (Exception ex) {
return StatusCode(500, ...);
}
}
✅ Good: Middleware で一括管理
// Controller は業務ロジックに集中できる
public async Task<IActionResult> GetUser(int id)
{
var user = await _service.GetUser(id);
return Ok(user);
// 例外は Middleware がキャッチして
// JSON レスポンスに変換する
}
ログレベルの方針
| 例外の種類 | ログレベル | 理由 |
|---|---|---|
| Validation / NotFound / BusinessRule | Warning | ユーザー起因のため(システムは正常) |
| Infrastructure / その他 | Error | システム障害のため(調査・対応が必要) |
🔗 参考リンク
- 📄 設計書: error-handling.md
- 💻 ソースコード(例外クラス): src/BlazorApp/Shared/Exceptions/
- 💻 ソースコード(Middleware): ExceptionHandlingMiddleware.cs
- 🧪 テストコード(例外クラス): ExceptionClassTests.cs
- 🧪 テストコード(Middleware): ExceptionHandlingMiddlewareTests.cs