

# API Gateway で Lambda エラーを処理する
<a name="handle-errors-in-lambda-integration"></a>

 Lambda カスタム統合の場合、統合レスポンスで Lambda によって返されたエラーを、クライアントの標準 HTTP エラーレスポンスにマップする必要があります。そうしないと、Lambda のエラーはデフォルトで `200 OK` レスポンスとして返されるため、API ユーザーは直感的に理解できません。

 Lambda から返されるエラーには、標準エラーとカスタムエラーの 2 種類があります。API では、これらを異なる方法で処理する必要があります。

 Lambda プロキシ統合では、Lambda は次の形式で出力を返す必要があります。

```
{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}
```

この出力で、通常、`statusCode` の `4XX` はクライアントエラー、`5XX` はサーバーエラーです。API Gateway では、これらのエラーを処理する方法として、指定された `statusCode` に従って Lambda エラーを HTTP エラーレスポンスにマッピングします。API Gateway がクライアントへのレスポンスの一部としてエラータイプ (`InvalidParameterException` など) を渡すには、Lambda 関数がヘッダー (`"X-Amzn-ErrorType":"InvalidParameterException"` など) を `headers` プロパティに含める必要があります。

**Topics**
+ [API Gateway で標準の Lambda エラーを処理する](#handle-standard-errors-in-lambda-integration)
+ [API Gateway でカスタム Lambda エラーを処理する](#handle-custom-errors-in-lambda-integration)

## API Gateway で標準の Lambda エラーを処理する
<a name="handle-standard-errors-in-lambda-integration"></a>

AWS Lambda の標準エラーは次の形式になります。

```
{
  "errorMessage": "<replaceable>string</replaceable>",
  "errorType": "<replaceable>string</replaceable>",
  "stackTrace": [
    "<replaceable>string</replaceable>",
    ...
  ]
}
```

 ここで、`errorMessage` はエラーの文字列式です。`errorType` は、言語に依存するエラーまたは例外タイプです。`stackTrace` は、エラーの発生につながったスタックトレースを示す文字列式のリストです。

 たとえば、次の JavaScript (Node.js) Lambda 関数について考えてみます。

```
export const handler = function(event, context, callback) {
    callback(new Error("Malformed input ..."));
};
```

この関数は、`Malformed input ...` をエラーメッセージとする、次の Lambda 標準エラーを返します。

```
{
  "errorMessage": "Malformed input ...",
  "errorType": "Error",
  "stackTrace": [
    "export const handler (/var/task/index.js:3:14)"
  ]
}
```

 同様に、次の例は同じ `Exception` をエラーメッセージとし、`Malformed input ...` をスローする Python Lambda 関数です。

```
def lambda_handler(event, context):
    raise Exception('Malformed input ...')
```

 この関数は、次の Lambda 標準エラーを返します。

```
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      3,
      "lambda_handler",
      "raise Exception('Malformed input ...')"
    ]
  ],
  "errorType": "Exception",
  "errorMessage": "Malformed input ..."
}
```

 `errorType` プロパティと `stackTrace` プロパティの値は、言語に依存します。この標準エラーは、`Error` オブジェクトの拡張または `Exception` クラスのサブクラスである各エラーオブジェクトにも適用されます。

 Lambda の標準エラーをメソッドレスポンスにマッピングするには、まず該当する Lambda エラーの HTTP スタータスコードを確認する必要があります。次に、その HTTP ステータスコードに関連付けられた [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) の `[selectionPattern](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)` プロパティで正規表現パターンを設定します。API Gateway コンソールの場合、この `selectionPattern` は各統合レスポンスの下の **[統合レスポンス]** セクションに、**[Lambda エラーの正規表現]** として表示されます。

**注記**  
API Gateway は、レスポンスマッピングに Java パターンスタイルの正規表現を使用します。詳細については、Oracle ドキュメントの「[パターン](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)」を参照してください。

 例えば、次の [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) を使用して新しい `selectionPattern` 式を設定します。

```
aws apigateway put-integration-response --rest-api-id z0vprf0mdh --resource-id x3o5ih --http-method GET --status-code 400 --selection-pattern "Malformed.*" --region us-west-2
```

 [メソッドレスポンス](api-gateway-method-settings-method-response.md#setup-method-response-status-code)で対応するエラーコード (`400`) も必ず設定します。そうしないと、ランタイムに API Gateway から無効な設定エラーレスポンスがスローされます。

**注記**  
 ランタイムに、API Gateway は Lambda エラーの `errorMessage` を `selectionPattern` プロパティの正規表現のパターンと照合します。一致すると、API Gateway は Lambda エラーを、対応する HTTP ステータスコードの HTTP レスポンスとして返します。一致しない場合、API Gateway はエラーをデフォルトレスポンスとして返すか、デフォルトレスポンスが設定されていなければ、無効な設定例外をスローします。  
 特定のレスポンスで `selectionPattern` の値を `.*` に設定すると、このレスポンスはデフォルトのレスポンスとしてリセットされます。このような選択パターンは null (任意の未指定のエラーメッセージ) を含むすべてのエラーメッセージに一致するためです。その結果のマッピングにより、デフォルトのマッピングが上書きされます。`.+` を選択パターンとして使用してレスポンスをフィルタする場合は、改行 ('`\n`) 文字を含むレスポンスには一致しない可能性があることに注意してください。

 `selectionPattern` を使用して既存の AWS CLI 値を更新するには、[update-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration-response.html) オペレーションを呼び出し、`/selectionPattern` のパス値を `Malformed*` パターンの指定された正規表現式に置き換えます。



API Gateway コンソールを使用して `selectionPattern` 式を設定するには、指定した HTTP ステータスコードの統合レスポンスを設定または更新するときに、**[Lambda エラーの正規表現]** テキストボックスに式を入力します。

## API Gateway でカスタム Lambda エラーを処理する
<a name="handle-custom-errors-in-lambda-integration"></a>

 AWS Lambda では、前のセクションで説明した標準エラーの代わりにカスタムエラーオブジェクトを JSON 文字列として返すことができます。エラーは、任意の有効な JSON オブジェクトです。たとえば、次の JavaScript (Node.js) Lambda 関数はカスタムエラーを返します。

```
export const handler = (event, context, callback) => {
    ...
    // Error caught here:
    var myErrorObj = {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
    callback(JSON.stringify(myErrorObj));
};
```

 `myErrorObj` を呼び出して関数を終了する前に、`callback` オブジェクトを JSON 文字列に変換する必要があります。そうしないと、`myErrorObj` は `"[object Object]"` の文字列として返されます。API のメソッドを前の Lambda 関数と統合すると、API Gateway は以下の内容をペイロードとする統合レスポンスを受け取ります。

```
{
    "errorMessage": "{\"errorType\":\"InternalServerError\",\"httpStatus\":500,\"requestId\":\"e5849002-39a0-11e7-a419-5bb5807c9fb2\",\"trace\":{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}}"
}
```

 通常の統合レスポンスと同様に、このエラーレスポンスはそのままメソッドレスポンスに渡すことができます。または、マッピングテンプレートを使用してペイロードを別の形式に変換することもできます。次の例は、ステータスコードが `500` のメソッドレスポンスの本文マッピングテンプレートです。

```
{
    errorMessage: $input.path('$.errorMessage');
}
```

このテンプレートは、カスタムエラーの JSON 文字列が含まれている統合レスポンス本文を、次のメソッドレスポンス本文に変換します。このメソッドレスポンス本文には、カスタムエラーの JSON オブジェクトが含まれています。

```
{
    "errorMessage" : {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
};
```

 API の要件によっては、カスタムエラープロパティの一部または全部をメソッドレスポンスのヘッダーパラメータとして渡す必要があります。そのためには、統合レスポンス本文からメソッドレスポンスヘッダーにカスタムエラーマッピングを適用します。

たとえば、次の OpenAPI 拡張は、`errorMessage.errorType`、`errorMessage.httpStatus`、`errorMessage.trace.function`、および `errorMessage.trace` プロパティから、それぞれ `error_type`、`error_status`、`error_trace_function`、および `error_trace` ヘッダーへのマッピングを定義します。

```
"x-amazon-apigateway-integration": {
    "responses": {
        "default": {
          "statusCode": "200",
          "responseParameters": {
            "method.response.header.error_trace_function": "integration.response.body.errorMessage.trace.function",
            "method.response.header.error_status": "integration.response.body.errorMessage.httpStatus",
            "method.response.header.error_type": "integration.response.body.errorMessage.errorType",
            "method.response.header.error_trace": "integration.response.body.errorMessage.trace"
          },
          ...
        }
    }
}
```

 ランタイムに、API Gateway は `integration.response.body` パラメータを逆シリアル化してヘッダーマッピングを行います。ただし、この逆シリアル化は、Lambda のカスタムエラーレスポンスの本文からヘッダーへのマッピングにのみ適用され、`$input.body` を使用した本文から本文へのマッピングには適用されません。これらのカスタムエラーの本文からヘッダーへのマッピングでは、クライアントはメソッドレスポンスの一部として以下のヘッダーを受け取ります (`error_status`、`error_trace`、`error_trace_function`、および `error_type` をメソッドリクエストで宣言している場合)。

```
"error_status":"500",
"error_trace":"{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}",
"error_trace_function":"abc()",
"error_type":"InternalServerError"
```

統合レスポンス本文の `errorMessage.trace` プロパティは複合プロパティです。これは JSON 文字列として `error_trace` ヘッダーにマッピングされます。