

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 處理 API Gateway 中的 Lambda 錯誤
<a name="handle-errors-in-lambda-integration"></a>

 對於 Lambda 自訂整合，您必須將整合回應中 Lambda 傳回的錯誤，映射到您用戶端的標準 HTTP 錯誤回應。否則，預設 Lambda 錯誤會傳回 `200 OK` 回應，此結果對您的 API 使用者不是直覺式。

 Lambda 會傳回兩種錯誤：標準錯誤和自訂錯誤。在您的 API 中，您必須以不同的方式處理它們。

 使用 Lambda 代理整合，Lambda 必須傳回格式如下的輸出：

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

在這個輸出中，`statusCode` 的用戶端錯誤通常是 `4XX`，伺服器錯誤通常是 `5XX`。API Gateway 處理這些錯誤的方法是，根據指定的 `statusCode`，將 Lambda 錯誤映射到 HTTP 錯誤回應。如需 API Gateway 將錯誤類型 (例如 `InvalidParameterException`) 當作回應的一部分傳送到用戶端，Lambda 函數必須在 `headers` 屬性中包含標頭 (例如 `"X-Amzn-ErrorType":"InvalidParameterException"`)。

**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 ..."));
};
```

此函數會傳回下列標準 Lambda 錯誤，包含 `Malformed input ...` 作為錯誤訊息：

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

 同樣地，請考慮下列 Python Lambda 函數，它會引發具有相同 `Malformed input ...` 錯誤訊息的 `Exception`。

```
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 錯誤 Regex**。

**注意**  
API Gateway 使用 Java 模式 regex 進行回應映射。如需詳細資訊，請參閱 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 會根據 `selectionPattern` 屬性規則表達式的模式比對 Lambda 錯誤的 `errorMessage`。若出現相符項目，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*`模式的指定 regex 表達式。



若要使用 API Gateway 主控台設定 `selectionPattern` 表達式，當設定或更新指定的 HTTP 狀態碼的整合回應時，請在 **Lambda 錯誤 Regex** 文字方塊中輸入表達式。

## 處理 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` 物件轉換為 JSON 字串，再呼叫 `callback` 結束函數。否則，`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` 屬性是複雜屬性。它會對應到 `error_trace` 標頭做為 JSON 字串。