Java 中的 AWS Lambda 函數錯誤 - AWS Lambda

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

Java 中的 AWS Lambda 函數錯誤

您的程式碼若引發錯誤,Lambda 將產生該項錯誤的 JSON 表示法。此錯誤文件會顯示在調用記錄中,同步調用的情況下還會顯示在輸出中。

此頁面說明如何使用 Lambda 主控台和 AWS CLI 來檢視 Java 執行時間的 Lambda 函數調用錯誤。

語法

在下列範例中,執行階段無法將事件還原序列化為物件。輸入是一個有效的 JSON 類型,但它與處理常式方法預期的類型不相符。

範例 Lambda 執行時間錯誤
{ "errorMessage": "An error occurred during JSON parsing", "errorType": "java.lang.RuntimeException", "stackTrace": [], "cause": { "errorMessage": "com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.lang.Integer from String value '1000,10': not a valid Integer value\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@35fc6dc4; line: 1, column: 1] (through reference chain: java.lang.Object[0])", "errorType": "java.io.UncheckedIOException", "stackTrace": [], "cause": { "errorMessage": "Can not construct instance of java.lang.Integer from String value '1000,10': not a valid Integer value\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@35fc6dc4; line: 1, column: 1] (through reference chain: java.lang.Object[0])", "errorType": "com.fasterxml.jackson.databind.exc.InvalidFormatException", "stackTrace": [ "com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:55)", "com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:907)", ... ] } } }

運作方式

當您調用 Lambda 函數時,Lambda 會接收調用請求,驗證執行角色中的許可,確認事件文件是否為有效的 JSON 文件,以及檢查參數值。

如果請求通過驗證,Lambda 會將請求傳送至函數執行個體。Lambda 執行時間環境會將事件文件轉換為物件,並將它傳遞至您的函數處理常式。

如果 Lambda 發生錯誤,它會傳回例外狀況類型、訊息,以及指出錯誤原因的 HTTP 狀態碼。調用 Lambda 函數的用戶端或服務能以程式設計方式來處理錯誤或將其傳遞給最終使用者。正確的錯誤處理行為取決於應用程式類型、對象和錯誤的來源而定。

下列清單說明您可以從 Lambda 中接收的狀態碼範圍。

2xx

回應中含有 X-Amz-Function-Error 標頭的 2xx 序列錯誤表示 Lambda 執行時間或函數錯誤。2xx 序列狀態碼表示 Lambda 接受請求,而非錯誤代碼,Lambda 透過在回應中包含 X-Amz-Function-Error 標頭來指示錯誤。

4xx

4xx 序列錯誤表示調用用戶端或服務可藉由修改請求、請求許可或重試請求來進行修正的錯誤。除 429 以外的 4xx 序列錯誤則表示請求錯誤。

5xx

5xx 序列錯誤表示 Lambda 存在問題,或函數的組態或資源存在問題。5xx 序列錯誤則可表示暫時狀況,使用者無需任何動作即可解決。調用用戶端或服務無法解決這些問題,但 Lambda 函數的擁有者可能可以修正該問題。

如需呼叫錯誤的完整清單,請參閱InvokeFunction 錯誤

建立傳回例外狀況的函數

您可以建立 Lambda 函數,以向使用者顯示人類可讀取的錯誤訊息。

注意

要測試此代碼,您需要在項目 src 文件夾中包含 InputLengthException.java。

範例 src /主/java/例子/.java HandlerDivide-運行時異常
import java.util.List; // Handler value: example.HandlerDivide public class HandlerDivide implements RequestHandler<List<Integer>, Integer>{ Gson gson = new GsonBuilder().setPrettyPrinting().create(); @Override public Integer handleRequest(List<Integer> event, Context context) { LambdaLogger logger = context.getLogger(); // process event if ( event.size() != 2 ) { throw new InputLengthException("Input must be a list that contains 2 numbers."); } int numerator = event.get(0); int denominator = event.get(1); logger.log("EVENT: " + gson.toJson(event)); logger.log("EVENT TYPE: " + event.getClass().toString()); return numerator/denominator; } }

當函數擲回 InputLengthException,Java 執行階段會將其序列化到下列文件。

範例 錯誤文件 (已新增空格)
{ "errorMessage":"Input must be a list that contains 2 numbers.", "errorType":"java.lang.InputLengthException", "stackTrace": [ "example.HandlerDivide.handleRequest(HandlerDivide.java:23)", "example.HandlerDivide.handleRequest(HandlerDivide.java:14)" ] }

在這個例子中,InputLengthException是一個RuntimeException. RequestHandler 介面不允許已檢查的例外狀況。該 RequestStreamHandler 介面支援擲回 IOException 錯誤。

上例中的 return 陳述式也可以擲回執行階段例外狀況。

return numerator/denominator;

此代碼會傳回一個算術錯誤。

{"errorMessage":"/ by zero","errorType":"java.lang.ArithmeticException","stackTrace":["example.HandlerDivide.handleRequest(HandlerDivide.java:28)","example.HandlerDivide.handleRequest(HandlerDivide.java:13)"]}

使用 Lambda 主控台

您可以透過設定測試事件和檢視輸出,來調用 Lambda 主控台上的函數。系統會在函數的執行日誌中擷取錯誤輸出,以及在 AWS X-Ray 中啟用主動追蹤時加以擷取。

若要在 Lambda 主控台中調用函數
  1. 開啟 Lambda 主控台中的 函數頁面

  2. 選擇要測試的函數,並選擇 Test (測試)。

  3. Test event (測試事件) 下方,選取 New event (新事件)。

  4. 選取 Template (範本)。

  5. 對於 Name (名稱),輸入測試的名稱。在文字輸入方塊中,輸入 JSON 測試事件。

  6. 選擇儲存變更

  7. 選擇 測試

Lambda 主控台會同步調用您的函數並顯示結果。若要查看回應、日誌和其他資訊,請展開 Details (詳細資料) 區段。

使用 AWS Command Line Interface​ (AWS CLI​)

AWS CLI 是開放原始碼工具,可讓您在命令列 shell 中使用命令來與 AWS 服務互動。若要完成本節中的步驟,您必須執行下列各項:

當您在 AWS CLI 中調用 Lambda 函數時,AWS CLI 會將回應分割成兩個文件。AWS CLI 回應會顯示在命令提示中。如果發生錯誤,則回應會包含 FunctionError 欄位。該函式傳回的調用回應或錯誤會寫入至輸出檔案。例如,output.jsonoutput.txt

下列調用命令範例示範了如何調用函數,並將調用回應寫入 output.txt 檔案。

aws lambda invoke \ --function-name my-function \ --cli-binary-format raw-in-base64-out \ --payload '{"key1": "value1", "key2": "value2", "key3": "value3"}' output.txt

如果您使用 AWS CLI 第 2 版,則需要 cli-binary-format 選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》AWS CLI 支援的全域命令列選項

您應在命令提示中看到 AWS CLI 回應:

{ "StatusCode": 200, "FunctionError": "Unhandled", "ExecutedVersion": "$LATEST" }

您應在 output.txt 檔案中看到函數調用回應。在相同的命令提示下,您還可以使用下列命令提示來檢視輸出:

cat output.txt

您應在命令提示下看到調用回應。

{"errorMessage":"Input must contain 2 numbers.","errorType":"java.lang.InputLengthException","stackTrace": ["example.HandlerDivide.handleRequest(HandlerDivide.java:23)","example.HandlerDivide.handleRequest(HandlerDivide.java:14)"]}

Lambda 也會在函數日誌中記錄高達 256 KB 的錯誤物件。如需詳細資訊,請參閱 AWS Lambda Java 中的函數日誌記錄

其他 AWS 服務中的錯誤處理

當另一項 AWS 服務調用您的函數時,服務會選擇調用類型和重試行為。AWS 服務可以按照排程調用您的函數、回應資源上的生命週期事件,或為使用者的請求服務。某些服務會以非同步方式呼叫函數,並讓 Lambda 處理錯誤,而其他服務則會重試或將錯誤傳回給使用者。

例如,API Gateway 會將所有呼叫和函數錯誤視為內部錯誤。如果 Lambda API 拒絕調用請求,則 API Gateway 會傳回 500 錯誤代碼。如果函數執行但傳回錯誤,或傳回格式錯誤的回應,API Gateway 會傳回錯誤代碼 502。若要自訂錯誤回應,您必須在程式碼中發現錯誤,並以必要的格式格式化回應。

我們建議使用 AWS X-Ray 來判斷錯誤的來源及其原因。X-Ray 可讓您找出哪個元件遇到錯誤,並查看錯誤的詳細資訊。下列範例顯示來自 API Gateway 的 502 回應中導致的函數錯誤。


          透過 API Gateway 處理函數錯誤的流程圖。

如需詳細資訊,請參閱 在 AWS Lambda 中檢測 Java 程式碼

範例應用程式

本指南的 GitHub 儲存庫包含示範如何使用錯誤的範例應用程式。每個範例應用程式都包含可輕鬆部署和清理的指令碼、AWS Serverless Application Model (AWS SAM) 範本和支援資源。

以 Java 編寫的範例 Lambda 應用程式
  • java17-examples – 一個 Java 函數,示範如何使用 Java 記錄來表示輸入事件資料物件。

  • java-basic - 具有單元測試和變數日誌組態的最小 Java 函數集合。

  • java-events - Java 函數集合,其中包含如何處理來自各種服務 (例如 Amazon API Gateway、Amazon SQS 和 Amazon Kinesis) 事件的骨架程式碼。這些函數使用最新版本的aws-lambda-java-events庫(3.0.0 及更新版本)。這些範例不需要 AWS 開發套件做為相依項目。

  • s3-java - 一種 Java 函數,它處理來自 Amazon S3 的通知事件,並使用 Java Class Library (JCL) 以從上傳的映像檔案建立縮圖。

  • 使用 API Gateway 調用 Lambda 函數 - 一個 Java 函數,其可掃描包含員工資訊的 Amazon DynamoDB 資料表。然後,其會使用 Amazon Simple Notification Service 向員工傳送文字訊息,慶祝他們的工作週年紀念日。此範例使用 API Gateway 調用函數。

java-basic 函數包含傳回自訂執行階段例外狀況的處理常式 (HandlerDivide)。HandlerStream 處理常式會實作 RequestStreamHandler 並會擲回一個 IOException 已檢查的例外狀況。

後續步驟?