Java 中的 Amazon Lambda 函数错误 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Java 中的 Amazon Lambda 函数错误

您的代码引发错误时,Lambda 将会生成错误的 JSON 表示形式。此错误文档会出现在调用日志和输出中,用于同步调用。

本页介绍如何使用 Lambda 控制台和 Amazon 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 系列错误指示调用客户端或服务可以通过修改请求、请求权限或重试请求来修复的错误。4xx 系列错误(而不是 429)通常指示请求存在错误。

5xx

5xx 系列错误指示 Lambda 问题,或者函数的配置或资源存在问题。5xx 系列错误可以指示无需用户采取任何操作即可解决的临时情况。调用客户端或服务无法解决这些问题,但 Lambda 函数的拥有者可能能够修复该问题。

有关调用错误的完整列表,请参阅InvokeFunction 错误

创建返回异常的函数

您可以创建向用户显示人类可读错误消息的 Lambda 函数。

注意

要测试此代码,你需要在项目 src 文件夹中加入 InputLengthException.java。

src/main/java/example/ .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是一个RuntimeExceptionRequestHandler 接口不允许检查到的异常。RequestStreamHandler 接口支持引发 IOException 错误。

前一个示例中的返回语句也可能引发运行时异常。

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 控制台上调用函数。输出也会捕获到函数的执行日志中,当启用 active tracing (活动跟踪) 时,会捕获到 Amazon X-Ray 中。

在 Lambda 控制台中调用函数
  1. 打开 Lamba 控制台的 Functions page(函数页面)。

  2. 选择要测试的函数,然后选择 Test(测试)。

  3. Test event(测试事件)中,选择 New event(新建事件)。

  4. 选择 Template(模板)。

  5. 对于 Name(名称),输入测试事件的名称。在文本输入框中,输入 JSON 测试事件。

  6. 选择 Save changes(保存更改)。

  7. 选择测试

Lambda 控制台会同步调用您的函数并显示结果。要查看响应、日志和其他信息,请展开 Details (详细信息) 部分。

使用 Amazon Command Line Interface (Amazon CLI)

Amazon CLI 是一种开源工具,让您能够在命令行 Shell 中使用命令与 Amazon 服务进行交互。要完成本节中的步骤,您必须满足以下条件:

在 Amazon CLI 中调用 Lambda 函数时,Amazon CLI 会将响应分为两个文档。Amazon 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

如果使用 cli-binary-format 版本 2,则 Amazon CLI 选项是必需的。要将其设为默认设置,请运行 aws configure set cli-binary-format raw-in-base64-out。有关更多信息,请参阅版本 2 的 Amazon Command Line Interface 用户指南中的 Amazon CLI 支持的全局命令行选项

命令提示符中应该会显示 Amazon 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。有关更多信息,请参阅Java 中的 Amazon Lambda 函数日志记录

其他 Amazon 服务中的错误处理

当其他 Amazon 服务调用您的函数时,服务会选择调用类型和重试行为。Amazon 服务可以按计划调用您的函数,以响应资源上的生命周期事件或者针对来自用户的请求提供响应。某些服务异步调用函数并让 Lambda 处理错误,而其他服务则重试或将错误传回给用户。

例如,API Gateway 将所有调用和函数错误视为内部错误。如果 Lambda API 拒绝调用请求,则 API Gateway 会返回 500 错误代码。如果函数运行但返回错误,或返回格式错误的响应,则 API Gateway 返回 502 错误代码。要自定义错误响应,您必须捕获代码中的错误并以所需格式设置响应的格式。

建议使用 Amazon X-Ray 来确定错误来源及其原因。您可使用 X-Ray 找出哪个组件遇到了错误,并查看有关错误的详细信息。以下示例显示导致 API Gateway 发出 502 响应的函数错误。


          使用 API Gateway 跟踪函数错误的映射。

有关更多信息,请参阅在 Amazon Lambda 中检测 Java 代码

示例应用程序

本指南的 GitHub 存储库包括演示错误用法的示例应用程序。每个示例应用程序都包含用于轻松部署和清理的脚本、一个 Amazon Serverless Application Model (Amazon 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 及更高版本)。这些示例不需要 Amazon 开发工具包作为依赖项。

  • s3-java – 此 Java 函数可处理来自 Amazon S3 的通知事件,并使用 Java 类库(JCL)从上传的图像文件创建缩略图。

  • 使用 API Gateway 调用 Lambda 函数 – Java 函数,用于扫描包含员工信息的 Amazon DynamoDB 表。然后,该函数使用 Amazon Simple Notification Service 向员工发送短信,祝贺他们工作周年纪念日快乐。此示例使用 API Gateway 调用函数。

java-basic 函数包括返回自定义运行时异常的处理程序 (HandlerDivide)。HandlerStream 处理程序实现 RequestStreamHandler 并可能引发 IOException 检查的异常。

接下来做什么?