AWS Lambda
开发人员指南

函数错误 (C#)

当 Lambda 函数出现异常时,Lambda 将向您报告异常信息。异常可能发生在两个不同位置:

  • 初始化(Lambda 加载您的代码,验证处理程序字符串并为非静态类创建实例)。

  • Lambda 函数调用。

序列化的异常信息将作为已建模的 JSON 对象的负载返回并被输出到 CloudWatch 日志中。

在初始化阶段,无效的处理程序字符串、违规的类型或方法(请参阅 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 部分中显示 AWS Lambda 返回的错误信息。

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

AWS Lambda 可能会重试失败的 Lambda 函数,具体视事件源而定。有关更多信息,请参阅 了解重试行为

函数错误处理

您可以创建自定义错误处理机制,直接从您的 Lambda 函数引发异常,并直接在 AWS Step Functions 状态机中进行处理 (重试或捕获)。有关更多信息,请参阅使用状态机处理错误情况

请将 CreateAccount 状态看作使用 Lambda 函数将客户的详细信息写入数据库的任务

  • 如果任务成功,会创建账户并发送欢迎电子邮件。

  • 如果用户尝试创建的账户用户名已存在,Lambda 函数将出错,状态机会建议其他用户名,并重试账户创建过程。

以下代码示例演示了如何执行此操作。请注意,C# 中的自定义错误必须扩展 Exception 类型。

namespace Example { public class AccountAlreadyExistsException : Exception { public AccountAlreadyExistsException(String message) : base(message) { } } } namespace Example { public class Handler { public static void CreateAccount() { throw new AccountAlreadyExistsException("Account is in use!"); } } }

您可以配置 Step Functions,使用 Catch 规则捕获错误。Lambda 会自动将错误名称设置为运行时异常的简单类名称:

{ "StartAt": "CreateAccount", "States": { "CreateAccount": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:CreateAccount", "Next": "SendWelcomeEmail", "Catch": [ { "ErrorEquals": ["AccountAlreadyExistsException"], "Next": "SuggestAccountName" } ] }, … } }

AWS Step Functions 可于运行时捕获错误,按照 Next 转换中指定的方式,转换SuggestAccountName 状态。

自定义错误处理机制使创建无服务器应用程序变得更加容易。此功能与 Lambda 编程模型 支持的所有语言相集成,您可以任选编辑语言设计您的应用程序,并进行混合搭配。

要进一步了解如何使用 AWS Step Functions 和 AWS Lambda 创建您自己的无服务器应用程序,请参阅 AWS Step Functions

本页内容: