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

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

C# 中的 Amazon Lambda 函数错误

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

本页介绍如何使用 Lambda 控制台和 Amazon CLI 查看 C# 运行时的 Lambda 函数调用错误。

语法

在初始化阶段,无效的处理程序字符串、违规的类型或方法(请参阅 Lambda 函数处理程序限制),或者其他任何验证方法(例如忘记设置串行器属性以及将 POCO 作为输入或输出类型)都可能引发异常。这些异常的类型为 LambdaException。例如:

{ "errorType": "LambdaException", "errorMessage": "Invalid lambda function handler: 'http://this.is.not.a.valid.handler/'. The valid format is 'ASSEMBLY::TYPE::METHOD'." }

如果您的构造函数引发异常,则该错误类型也是 LambdaException,但构造过程中引发的异常将在本身即为已建模异常对象的 cause 属性中提供。

{ "errorType": "LambdaException", "errorMessage": "An exception was thrown when the constructor for type 'LambdaExceptionTestFunction.ThrowExceptionInConstructor' was invoked. Check inner exception for more details.", "cause": { "errorType": "TargetInvocationException", "errorMessage": "Exception has been thrown by the target of an invocation.", "stackTrace": [ "at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean&canBeCached, RuntimeMethodHandleInternal&ctor, Boolean& bNeedSecurityCheck)", "at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)", "at System.Activator.CreateInstance(Type type, Boolean nonPublic)", "at System.Activator.CreateInstance(Type type)" ], "cause": { "errorType": "ArithmeticException", "errorMessage": "Sorry, 2 + 2 = 5", "stackTrace": [ "at LambdaExceptionTestFunction.ThrowExceptionInConstructor..ctor()" ] } } }

如示例所示,内部异常将始终保留(作为 cause 属性),并且可进行深层嵌套。

调用期间也会发生异常。在这种情况下,异常类型将被保留,异常直接作为负载返回,并在 CloudWatch 日志中返回。例如:

{ "errorType": "AggregateException", "errorMessage": "One or more errors occurred. (An unknown web exception occurred!)", "stackTrace": [ "at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)", "at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)", "at lambda_method(Closure , Stream , Stream , ContextInfo )" ], "cause": { "errorType": "UnknownWebException", "errorMessage": "An unknown web exception occurred!", "stackTrace": [ "at LambdaDemo107.LambdaEntryPoint.<GetUriResponse>d__1.MoveNext()", "--- End of stack trace from previous location where exception was thrown ---", "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()", "at LambdaDemo107.LambdaEntryPoint.<CheckWebsiteStatus>d__0.MoveNext()" ], "cause": { "errorType": "WebException", "errorMessage": "An error occurred while sending the request. SSL peer certificate or SSH remote key was not OK", "stackTrace": [ "at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)", "at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)", "--- End of stack trace from previous location where exception was thrown ---", "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()", "at LambdaDemo107.LambdaEntryPoint.<GetUriResponse>d__1.MoveNext()" ], "cause": { "errorType": "HttpRequestException", "errorMessage": "An error occurred while sending the request.", "stackTrace": [ "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)", "at System.Net.Http.HttpClient.<FinishSendAsync>d__58.MoveNext()", "--- End of stack trace from previous location where exception was thrown ---", "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)", "at System.Net.HttpWebRequest.<SendRequest>d__63.MoveNext()", "--- End of stack trace from previous location where exception was thrown ---", "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)", "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)", "at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)" ], "cause": { "errorType": "CurlException", "errorMessage": "SSL peer certificate or SSH remote key was not OK", "stackTrace": [ "at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error)", "at System.Net.Http.CurlHandler.MultiAgent.FinishRequest(StrongToWeakReference`1 easyWrapper, CURLcode messageResult)" ] } } } } }

根据调用类型传达错误信息的方法:

  • RequestResponse 调用类型(即同步执行):在这种情况下,您会收到错误消息。

    例如,使用 Lambda 控制台调用 Lambda 函数时,调用类型始终为 RequestResponse,控制台将在其 Execution result(执行结果)部分中显示 Amazon Lambda 返回的错误信息。

  • Event 调用类型(即异步执行):在这种情况下,Amazon Lambda 不返回任何信息。相反,它会在 CloudWatch 日志和 CloudWatch 指标中记录错误信息。

工作方式

调用 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 控制台

您可以通过配置测试事件并查看输出,在 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

命令提示符中应该会显示调用响应。

Lambda 还会在函数日志中记录错误对象,最多 256 KB。有关更多信息,请参阅采用 C# 的 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 中检测 C# 代码

接下来做什么?