處理 API Gateway 中的 Lambda 錯誤 - Amazon API Gateway

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

處理 API Gateway 中的 Lambda 錯誤

對於 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")。

處理 API Gateway 中的標準 Lambda 錯誤

標準 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 ..." }

請注意,errorTypestackTrace 屬性值為語言相關。標準錯誤也適用於為 Error 物件延伸或 Exception 類別子類別的任何錯誤物件。

若要將標準 Lambda 錯誤映射到方法回應,您必須先決定指定 Lambda 錯誤的 HTTP 狀態碼。然後,您要在與指定的 HTTP 狀態碼相關聯之 IntegrationResponseselectionPattern 屬性上,設定規則表達式模式。在 API Gateway 主控台中,於每個整合回應下的整合回應區段中,這個 selectionPattern 會表示為 Lambda 錯誤 Regex

注意

API Gateway 使用 Java 模式 regex 進行回應映射。如需詳細資訊,請參閱 Oracle 文件中的模式一節。

例如,若要使用 selectionPattern 設定新的 AWS CLI 表達式,請呼叫下列 put-integration-response 命令:

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

請務必也要在方法回應上設定對應的錯誤碼 (400)。否則,API Gateway 在執行時間會擲出無效的組態錯誤回應。

注意

在執行時間,API Gateway 會根據 selectionPattern 屬性規則表達式的模式比對 Lambda 錯誤的 errorMessage。若出現相符項目,API Gateway 會傳回 Lambda 錯誤做為對應 HTTP 狀態碼的 HTTP 回應。如果沒有相符項目,API Gateway 會傳回錯誤作為預設回應,或者若未設定預設回應,則擲出無效的組態例外狀況。

將指定回應數量的 selectionPattern 值設為 .*,將這個回應重新設定為預設回應。這是因為這種選取模式會比對所有的錯誤訊息,包括 Null,即任何未指定的錯誤訊息。產生的對應會覆寫預設的對應。

若要使用 selectionPattern 更新現有的 AWS CLI 值,請呼叫 update-integration-response 操作,將 /selectionPattern 路徑值替換成 Malformed* 模式的指定 regex 表達式。

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

處理 API Gateway 中的自訂 Lambda 錯誤

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.errorTypeerrorMessage.httpStatuserrorMessage.trace.functionerrorMessage.trace 屬性到 error_typeerror_statuserror_trace_functionerror_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_statuserror_traceerror_trace_functionerror_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 字串。