エラーカテゴリとレスポンス設計
エラーカテゴリ定義
TASHIKA のエラーを4つのカテゴリに分類し、それぞれ異なるリトライ戦略・ユーザーメッセージ戦略を適用する:
| カテゴリ | HTTP ステータス | 例 | リトライ | ユーザーメッセージ戦略 |
|---|---|---|---|---|
| Validation(入力検証) | 400 | 必須フィールド未入力、形式不正、ファイルサイズ超過 | なし | フィールドレベルエラー + サマリ表示 |
| Authentication/Authorization(認証・認可) | 401 / 403 | トークン期限切れ、権限不足、MFA 未完了 | 401: リフレッシュ後リトライ / 403: リトライなし | 401: ログイン画面へリダイレクト / 403: 権限不足メッセージ |
| Business Logic(ビジネスロジック) | 409 / 422 | 申告が既に確定済み、承認の前提条件未達、税年度ロック済み | なし | ビジネス上の理由を具体的に説明 |
| System(システム) | 500 / 502 / 503 | DB タイムアウト、外部サービス障害、計算エンジン異常 | あり(Exponential Backoff) | 汎用メッセージ + TraceId 表示 |
RFC 7807 Problem Details 拡張
TASHIKA では RFC 7807 Problem Details を基本とし、traceId および errorCode をカスタム拡張フィールドとして追加する:
→ 関連: API 設計ルール
json
{
"type": "https://tashika.example/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "入力内容に誤りがあります。修正してください。",
"instance": "/api/v1/2025/declarations/123",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"errorCode": "TSHK-VAL-001",
"errors": {
"familyMembers[0].income": [
"所得見積額は0以上の整数で入力してください"
],
"insuranceDeductions[2].amount": [
"保険料額は保険種別の上限額(120,000円)以下で入力してください"
]
}
}Business Logic エラーの例:
json
{
"type": "https://tashika.example/errors/business/declaration-already-finalized",
"title": "Declaration Already Finalized",
"status": 409,
"detail": "この申告は既に確定済みです。訂正が必要な場合は管理者に再年調を依頼してください。",
"instance": "/api/v1/2025/declarations/456",
"traceId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"errorCode": "TSHK-BIZ-001"
}System エラーの例:
json
{
"type": "https://tashika.example/errors/system/service-unavailable",
"title": "Service Temporarily Unavailable",
"status": 503,
"detail": "システムが一時的に利用できません。しばらく時間をおいてから再度お試しください。",
"instance": "/api/v1/2025/declarations",
"traceId": "f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6",
"errorCode": "TSHK-SYS-001"
}エラーコードレジストリ
エラーコードのフォーマット: TSHK-{CATEGORY}-{3桁連番}
| カテゴリコード | カテゴリ名 |
|---|---|
VAL | Validation(入力検証) |
AUTH | Authentication/Authorization(認証・認可) |
BIZ | Business Logic(ビジネスロジック) |
SYS | System(システム) |
初期エラーコード一覧
Validation(入力検証):
| エラーコード | 説明 | HTTP |
|---|---|---|
TSHK-VAL-001 | リクエストボディのスキーマ検証失敗 | 400 |
TSHK-VAL-002 | ファイル形式が非対応(JPEG/PNG/PDF/XML/HEIC 以外) | 400 |
TSHK-VAL-003 | ファイルサイズ上限超過(10MB) | 400 |
TSHK-VAL-004 | マイナンバーのチェックデジット検証失敗 | 400 |
TSHK-VAL-005 | 税年度のフォーマット不正またはサポート範囲外 | 400 |
Authentication/Authorization(認証・認可):
| エラーコード | 説明 | HTTP |
|---|---|---|
TSHK-AUTH-001 | アクセストークン期限切れ | 401 |
TSHK-AUTH-002 | リフレッシュトークン無効または期限切れ | 401 |
TSHK-AUTH-003 | MFA 認証が必要 | 403 |
TSHK-AUTH-004 | 同時セッション数上限(3)に到達 | 403 |
TSHK-AUTH-005 | 操作に必要なロール/権限が不足 | 403 |
Business Logic(ビジネスロジック):
| エラーコード | 説明 | HTTP |
|---|---|---|
TSHK-BIZ-001 | 申告が既に確定済み(Finalized)で変更不可 | 409 |
TSHK-BIZ-002 | 承認の前提条件未達(未提出の申告を承認しようとした) | 422 |
TSHK-BIZ-003 | 税年度がロック済みで新規申告を作成不可 | 409 |
TSHK-BIZ-004 | 楽観的排他制御の競合(他のユーザーが先に更新) | 409 |
TSHK-BIZ-005 | 一括操作の部分失敗(成功/失敗の内訳を含む) | 422 |
TSHK-BIZ-006 | ウイルス検出によりファイルアップロード拒否 | 422 |
System(システム):
| エラーコード | 説明 | HTTP |
|---|---|---|
TSHK-SYS-001 | サービス一時利用不可(一般) | 503 |
TSHK-SYS-002 | DB コネクションタイムアウト | 503 |
TSHK-SYS-003 | 外部サービス障害(Circuit Breaker Open) | 502 |
TSHK-SYS-004 | 税額計算エンジンの内部エラー | 500 |
TSHK-SYS-005 | 非同期ジョブキュー飽和 | 503 |