🔴 エラー概要
POST /articles エンドポイントで存在しないユーザーIDを指定して記事を作成しようとした際、500 Internal Server Error が返されています。本来は400 Bad Requestとして適切なバリデーションエラーメッセージを返すべきです。
🔍 根本原因
-
問題箇所: src/lambda/sample-app/index.ts:265
-
原因: createArticle 関数内で外部User APIのエラーコード E1001(ユーザーが存在しない)を受け取った際、CriticalUserError を throw して処理を中断しています。しかし、外部API仕様書によれば、E1001は「ユーザーが存在しない」というバリデーションエラーであり、500エラーではなく400エラーとして処理すべきです。
-
コードの問題:
// src/lambda/sample-app/index.ts:260-274
// エラーハンドリング
if (!responseData.success) {
const errorCode = responseData.code;
const criticalErrors = ['E1001', 'E1003'];
if (criticalErrors.includes(errorCode)) {
throw new CriticalUserError(
'EXTERNAL_SERVICE_ERROR',
'External service error',
{
externalErrorCode: errorCode,
authorId,
operation: 'createArticle'
}
);
}
// ...
}
問題点:
-
E1001はバリデーションエラー: 外部API仕様書(docs/api-specs/user-api.yaml:51-80)によれば、E1001は「ユーザーが存在しない」エラーであり、データ整合性の問題です。記事作成時に存在しないユーザーIDが指定された場合は、ART-003(バリデーションエラー)として400エラーを返すべきです。
-
E1003も同様にバリデーションエラー: E1003は「ユーザーアカウント削除済み」であり、削除済みユーザーで記事を作成することは許可されるべきではありません。これもバリデーションエラーとして処理すべきです。
-
エラーメッセージが曖昧: "External service error" という曖昧なメッセージでは、クライアント側で何が問題なのか分かりません。「指定されたユーザーIDが存在しません」のような具体的なメッセージが必要です。
📊 影響範囲
- 影響を受ける機能:
- 影響を受けるユーザー:
- API クライアント開発者(存在しないユーザーIDで記事を作成しようとした場合、500エラーが返され、何が問題なのか分からない)
- フロントエンド開発者(バグやデータ不整合により無効なユーザーIDが送信された場合)
- 深刻度: High
- 500エラーはサーバー内部エラーを意味するため、クライアント側で適切なエラーハンドリングができない
- 本番環境でアラートが発生し、不要な調査工数が発生する
- ユーザー体験の悪化(適切なエラーメッセージが表示されない)
🛠️ 修正方法
createArticle 関数のエラーハンドリングを修正し、E1001/E1003を Critical エラーではなくバリデーションエラーとして処理します。
// src/lambda/sample-app/index.ts:260-281
// エラーハンドリング
if (!responseData.success) {
const errorCode = responseData.code;
// E1001: ユーザーが存在しない → バリデーションエラー
if (errorCode === 'E1001') {
return createErrorResponse(400, 'ART-003', '記事の作成に失敗しました', {
invalidFields: {
authorId: '指定されたユーザーIDが存在しません',
},
externalErrorCode: errorCode,
});
}
// E1003: ユーザーアカウント削除済み → バリデーションエラー
if (errorCode === 'E1003') {
return createErrorResponse(400, 'ART-003', '記事の作成に失敗しました', {
invalidFields: {
authorId: '指定されたユーザーは削除済みです',
},
externalErrorCode: errorCode,
});
}
// E1002 (アカウント停止), E2001 (レート制限), E3001 (内部エラー) などはフォールバック処理
console.warn(`User API returned error during article creation: ${errorCode}`, {
authorId,
errorCode
});
// その他のエラーは警告のみで処理を継続(既存のロジック)
}
重要な変更点:
- E1001とE1003を
CriticalUserError として throw するのではなく、400 Bad Request として適切なエラーレスポンスを返す
- エラーメッセージを具体的に(「ユーザーIDが存在しません」「削除済みユーザーです」)
- クライアント側で適切にエラーをハンドリングできるようにする
🚀 再発防止策
-
外部API仕様書の理解を深める: 外部APIのエラーコードの意味を正しく理解し、適切なエラーハンドリングを行う。「Critical」という分類は、本システムにとって致命的かどうかではなく、外部API側の分類であることに注意。
-
エラーコード分類の見直し:
- E1001(ユーザー不存在)とE1003(削除済み)はバリデーションエラー → 400エラー
- E1002(アカウント停止)はフォールバック可能 → 警告のみ、デフォルト値で処理継続
- E2001(レート制限)はリトライ可能 → 警告のみ、またはリトライロジック
- E3001(内部エラー)は真の Critical エラー → 500エラー or リトライ
-
統合テストの追加:
- 存在しないユーザーIDで記事作成を試みるテストケース
- 削除済みユーザーIDで記事作成を試みるテストケース
- それぞれが400エラーを返すことを確認
-
同様の問題の確認: getArticleById 関数でも同じパターンでE1001/E1003を Critical として扱っているため、そちらも修正が必要。ただし、getArticleById の場合は記事取得のコンテキストなので、フォールバック処理(デフォルト値での継続)が適切な可能性もある。
📝 検知情報
エラータイプ: CriticalUserError
エラーメッセージ: External service error
発生時刻: 2025-11-27T09:39:09.203Z
コンテキスト: POST /articles
ログソース: /aws/lambda/llm-ops-sample-app
スタックトレース
CriticalUserError: External service error
at createArticle (/var/task/index.js:212:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async Runtime.handler (/var/task/index.js:309:20)
🔴 エラー概要
POST /articles エンドポイントで存在しないユーザーIDを指定して記事を作成しようとした際、500 Internal Server Error が返されています。本来は400 Bad Requestとして適切なバリデーションエラーメッセージを返すべきです。
🔍 根本原因
問題箇所:
src/lambda/sample-app/index.ts:265原因:
createArticle関数内で外部User APIのエラーコードE1001(ユーザーが存在しない)を受け取った際、CriticalUserErrorを throw して処理を中断しています。しかし、外部API仕様書によれば、E1001は「ユーザーが存在しない」というバリデーションエラーであり、500エラーではなく400エラーとして処理すべきです。コードの問題:
問題点:
E1001はバリデーションエラー: 外部API仕様書(
docs/api-specs/user-api.yaml:51-80)によれば、E1001は「ユーザーが存在しない」エラーであり、データ整合性の問題です。記事作成時に存在しないユーザーIDが指定された場合は、ART-003(バリデーションエラー)として400エラーを返すべきです。E1003も同様にバリデーションエラー: E1003は「ユーザーアカウント削除済み」であり、削除済みユーザーで記事を作成することは許可されるべきではありません。これもバリデーションエラーとして処理すべきです。
エラーメッセージが曖昧: "External service error" という曖昧なメッセージでは、クライアント側で何が問題なのか分かりません。「指定されたユーザーIDが存在しません」のような具体的なメッセージが必要です。
📊 影響範囲
🛠️ 修正方法
createArticle関数のエラーハンドリングを修正し、E1001/E1003を Critical エラーではなくバリデーションエラーとして処理します。重要な変更点:
CriticalUserErrorとして throw するのではなく、400 Bad Request として適切なエラーレスポンスを返す🚀 再発防止策
外部API仕様書の理解を深める: 外部APIのエラーコードの意味を正しく理解し、適切なエラーハンドリングを行う。「Critical」という分類は、本システムにとって致命的かどうかではなく、外部API側の分類であることに注意。
エラーコード分類の見直し:
統合テストの追加:
同様の問題の確認:
getArticleById関数でも同じパターンでE1001/E1003を Critical として扱っているため、そちらも修正が必要。ただし、getArticleByIdの場合は記事取得のコンテキストなので、フォールバック処理(デフォルト値での継続)が適切な可能性もある。📝 検知情報
スタックトレース