コンテンツにスキップ

エラーハンドリング

エラーレスポンス形式

エラーが発生した場合、APIは以下の形式でエラー情報を返します:

{
"error": "error_code",
"error_description": "エラーの詳細説明",
"details": {
"field": "追加情報(オプション)"
}
}

フィールド説明

フィールド説明
errorstringエラーコード(機械可読)
error_descriptionstringエラーの説明(人間可読)
detailsobject追加のエラー詳細(オプション)

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ステータス説明
unauthorized401認証情報が無効または未提供
token_expired401トークンの有効期限切れ
token_revoked401トークンが無効化されている
forbidden403権限不足
insufficient_scope403必要なスコープが不足

リソースエラー

エラーコードHTTPステータス説明
not_found404リソースが見つからない
user_not_found404ユーザーが見つからない
client_not_found404クライアントが見つからない
organization_not_found404組織が見つからない
role_not_found404ロールが見つからない
policy_not_found404ポリシーが見つからない
flow_not_found404フローが見つからない

バリデーションエラー

エラーコードHTTPステータス説明
invalid_request400リクエスト形式が不正
validation_error422入力データのバリデーション失敗
invalid_email422メールアドレスの形式が不正
invalid_password422パスワードが要件を満たさない
invalid_json400JSONの解析に失敗

競合エラー

エラーコードHTTPステータス説明
conflict409リソースの競合
email_already_exists409メールアドレスが既に使用されている
client_id_already_exists409クライアントIDが既に使用されている
role_already_assigned409ロールが既に割り当てられている

状態エラー

エラーコードHTTPステータス説明
user_suspended403ユーザーが停止中
user_locked403ユーザーがロックされている
client_disabled403クライアントが無効化されている
flow_inactive400フローが非アクティブ

ジョブエラー

エラーコードHTTPステータス説明
job_not_found404ジョブが見つからない
job_failed500ジョブの実行に失敗
job_cancelled400ジョブがキャンセルされた
import_failed422インポート処理に失敗
export_failed500エクスポート処理に失敗

システムエラー

エラーコードHTTPステータス説明
internal_error500内部サーバーエラー
service_unavailable503サービス一時停止中
database_error500データベースエラー
timeout504リクエストタイムアウト

エラーハンドリングのベストプラクティス

リトライ戦略

一時的なエラー(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を添えてください。

詳細エラーモード

開発環境では、詳細なエラー情報を有効にできます:

Terminal window
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"
}
}