エラーハンドリング
エラーレスポンス形式
エラーが発生した場合、APIは以下の形式でエラー情報を返します:
{ "error": "error_code", "error_description": "エラーの詳細説明", "details": { "field": "追加情報(オプション)" }}フィールド説明
| フィールド | 型 | 説明 |
|---|---|---|
error | string | エラーコード(機械可読) |
error_description | string | エラーの説明(人間可読) |
details | object | 追加のエラー詳細(オプション) |
HTTPステータスコード別エラー
400 Bad Request
リクエストの形式が不正な場合:
{ "error": "invalid_request", "error_description": "リクエストボディのJSONが不正です"}401 Unauthorized
認証に失敗した場合:
{ "error": "unauthorized", "error_description": "認証トークンが無効または期限切れです"}403 Forbidden
権限が不足している場合:
{ "error": "forbidden", "error_description": "この操作を実行する権限がありません"}404 Not Found
リソースが見つからない場合:
{ "error": "not_found", "error_description": "指定されたユーザーが見つかりません"}409 Conflict
リソースの競合が発生した場合:
{ "error": "conflict", "error_description": "このメールアドレスは既に使用されています"}422 Unprocessable Entity
バリデーションエラーの場合:
{ "error": "validation_error", "error_description": "入力データが不正です", "details": { "email": "有効なメールアドレスを入力してください", "name": "名前は必須です" }}429 Too Many Requests
レート制限を超過した場合:
{ "error": "rate_limit_exceeded", "error_description": "レート制限を超過しました", "retry_after": 60}500 Internal Server Error
サーバー内部エラーの場合:
{ "error": "internal_error", "error_description": "内部エラーが発生しました。しばらくしてから再試行してください。"}エラーコード一覧
認証・認可エラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
unauthorized | 401 | 認証情報が無効または未提供 |
token_expired | 401 | トークンの有効期限切れ |
token_revoked | 401 | トークンが無効化されている |
forbidden | 403 | 権限不足 |
insufficient_scope | 403 | 必要なスコープが不足 |
リソースエラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
not_found | 404 | リソースが見つからない |
user_not_found | 404 | ユーザーが見つからない |
client_not_found | 404 | クライアントが見つからない |
organization_not_found | 404 | 組織が見つからない |
role_not_found | 404 | ロールが見つからない |
policy_not_found | 404 | ポリシーが見つからない |
flow_not_found | 404 | フローが見つからない |
バリデーションエラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
invalid_request | 400 | リクエスト形式が不正 |
validation_error | 422 | 入力データのバリデーション失敗 |
invalid_email | 422 | メールアドレスの形式が不正 |
invalid_password | 422 | パスワードが要件を満たさない |
invalid_json | 400 | JSONの解析に失敗 |
競合エラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
conflict | 409 | リソースの競合 |
email_already_exists | 409 | メールアドレスが既に使用されている |
client_id_already_exists | 409 | クライアントIDが既に使用されている |
role_already_assigned | 409 | ロールが既に割り当てられている |
状態エラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
user_suspended | 403 | ユーザーが停止中 |
user_locked | 403 | ユーザーがロックされている |
client_disabled | 403 | クライアントが無効化されている |
flow_inactive | 400 | フローが非アクティブ |
ジョブエラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
job_not_found | 404 | ジョブが見つからない |
job_failed | 500 | ジョブの実行に失敗 |
job_cancelled | 400 | ジョブがキャンセルされた |
import_failed | 422 | インポート処理に失敗 |
export_failed | 500 | エクスポート処理に失敗 |
システムエラー
| エラーコード | HTTPステータス | 説明 |
|---|---|---|
internal_error | 500 | 内部サーバーエラー |
service_unavailable | 503 | サービス一時停止中 |
database_error | 500 | データベースエラー |
timeout | 504 | リクエストタイムアウト |
エラーハンドリングのベストプラクティス
リトライ戦略
一時的なエラー(5xx系)に対しては、指数バックオフでリトライすることを推奨します:
async function fetchWithRetry(url, options, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const response = await fetch(url, options);
if (response.status === 429) { // レート制限:retry_afterを待つ const retryAfter = parseInt(response.headers.get('Retry-After') || '60'); await sleep(retryAfter * 1000); continue; }
if (response.status >= 500) { // サーバーエラー:指数バックオフ await sleep(Math.pow(2, i) * 1000); continue; }
return response; } catch (error) { if (i === maxRetries - 1) throw error; await sleep(Math.pow(2, i) * 1000); } }}エラーログの記録
APIエラーは適切にログに記録してください:
try { const response = await adminApi.createUser(userData);} catch (error) { console.error('ユーザー作成エラー:', { error_code: error.error, description: error.error_description, details: error.details, request_id: error.request_id });}ユーザーへのフィードバック
エラーメッセージはユーザーにわかりやすく表示してください:
function getErrorMessage(error) { switch (error.error) { case 'email_already_exists': return 'このメールアドレスは既に登録されています。'; case 'validation_error': return Object.values(error.details).join('\n'); case 'rate_limit_exceeded': return 'リクエストが多すぎます。しばらくお待ちください。'; default: return 'エラーが発生しました。しばらくしてから再試行してください。'; }}デバッグ情報
リクエストID
すべてのレスポンスには X-Request-ID ヘッダーが含まれます:
X-Request-ID: req_abc123xyzサポートへの問い合わせ時には、このリクエストIDを添えてください。
詳細エラーモード
開発環境では、詳細なエラー情報を有効にできます:
curl -X POST "https://{tenant-domain}/api/admin/users" \ -H "Authorization: Bearer {token}" \ -H "X-Debug: true" \ -d '{...}'レスポンス:
{ "error": "validation_error", "error_description": "入力データが不正です", "details": { "email": "有効なメールアドレスを入力してください" }, "debug": { "stack_trace": "...", "request_body": {...}, "timestamp": "2024-01-22T10:30:00Z" }}