According to this example in "AWS Lambda Developer Guide", custom exception can be caught by Step Function State's Catch
clause using ErrorEquals
with the custom exception type name.
This works for Node.js, .Net Core 1.0. But it does not work for .Net Core 2.0.
With .Net Core 2.0, it gets the following output on the step that throws the custom exception:
{
"Error": "Lambda.Unknown",
"Cause": "The cause could not be determined because Lambda did not return an error type."
}
While with .Net Core 1.0, it gets the expected one as below:
{
"Error": "CustomError",
"Cause": "{\n \"errorType\": \"CustomError\",\n \"errorMessage\": \"This is a custom error!\",\n \"stackTrace\": [\n \"at FailFunctionNet.Function.FunctionHandler(String input, ILambdaContext context)\",\n \"at lambda_method(Closure , Stream , Stream , ContextInfo )\"\n ]\n}\n"
}
You must return an exception that inherits directly from an exception for some reason. I personally don't understand the reason for this limitation. Also, the handling of exception thrown from async code is suboptimal, there no reason to present aggregate exception and not the real exception.
@tsibelman Return an exception? But throw exception does work for .Net Core 1.0. It does not work for .Net Core 2.0 only. And I do derive from System.Exception
for my CustomError
c#
public class CustomError: Exception {
public CustomError(string message)
: base(message) {}
// ...
}
I meant throw sorry, I encounter issue liked your when I used some of the basic exceptions from a framework like ArgumentNullException, but you say it not a case for you.
@mercury-jin-autodesk , I'm not able to replicate this issue with .NET Core 2.0. If I throw a custom exception I get the following output from the Lambda function
{
"errorType": "CustomerNotfoundException",
"errorMessage": "Abc not found",
"stackTrace": [
"at Test.Function.FunctionHandler(String input, ILambdaContext context)",
"at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
]
}
Could you share the code snippet for a minimal repro, with code for Lambda function and the exception type?
@gokarnm
Running the lambda function directly through Lambda console would result the expected error. But when I connect it into a state machine in Step Functions, the Catch
clause does not work only for .Net Core 2.0.
My lambda function codes:
```c#
using Amazon.Lambda.Core;
using System;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
namespace FailFunctionNet
{
public class CustomError: Exception
{
public CustomError(string message)
: base(message)
{
}
}
public class Function
{
public string FunctionHandler(string input, ILambdaContext context)
{
throw new CustomError("This is a custom error!");
}
}
}
My state machine:
```json
{
"Comment": "A Catch example of the Amazon States Language using an AWS Lambda Function",
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:************:function:FailFunctionNet",
"Catch": [
{
"ErrorEquals": ["CustomError"],
"Next": "CustomErrorFallback"
},
{
"ErrorEquals": ["States.TaskFailed"],
"Next": "ReservedTypeFallback"
},
{
"ErrorEquals": ["States.ALL"],
"Next": "CatchAllFallback"
}
],
"End": true
},
"CustomErrorFallback": {
"Type": "Pass",
"Result": "This is a fallback from a custom lambda function exception",
"End": true
},
"ReservedTypeFallback": {
"Type": "Pass",
"Result": "This is a fallback from a reserved error code",
"End": true
},
"CatchAllFallback": {
"Type": "Pass",
"Result": "This is a fallback from a reserved error code",
"End": true
}
}
}
And the result
@mercury-jin-autodesk , this is due to a bug in serializing exceptions thrown from a Lambda function. We are working on a fix which should be released soon.
Could you share the response from directly invoking your Lambda function when it throws an exception? There may be a workaround to unblock you while we push the fix.
Running the lambda function directly, and I got the following.
@gokarnm Any eta on the fix for this bug? Thanks.
Hi @mercury-jin-autodesk , the workaround is to disable PDB files, the file paths in the error response are not being serialized correctly. You can do this by setting the following in the csproj file.
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugType>None</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
Hi @mabublue , I'm not able to provide an ETA. This issue is being prioritized and we should release a fix soon. Does the provided workaround help address the issue till we release a fix?
Thanks @gokarnm , I will give it a try.
@gokarnm
The workaround works. Thank you.
Hi @gokarnm
I have also tried the workaround successfully. Many thanks.
The workaround also worked for me. It would be nice if this, and async
not returning AggregateException
would be fixed. I'm currently manually unwrapping AggregateException
before throwing from a synchronous entry point. It's a bit silly.
The fix for this issue has been deployed to production.
Is this issue really resolved? i am using async
lambda with .Net core 2.0 and state machine still receiving AggregateException
The fix was made in the .NET Core 2.1 runtime. Since Microsoft has put .NET Core 2.0 out of support I would recommend migrating to the .NET Core 2.1 runtime which has long term support.
My original project was 2.0. I have already converted my project to 2.1 and deployed. still see the same issue. I read same issue posted here
Did you try setting the environment UNWRAP_AGGREGATE_EXCEPTIONS
to 1 as mentioned in reddit?
Here's the reddit post: https://www.reddit.com/r/aws/comments/98witj/we_are_the_aws_net_team_ask_the_experts/e98xinf
I have not tried, thought it was temporary fix. I thought default behavior should be unwrapped and that was the fix you put in.
We couldn't change the default behavior in the .NET Core 2.1 runtime because it's a breaking change. But we agree, and it will be the default in future versions.
Most helpful comment
The workaround also worked for me. It would be nice if this, and
async
not returningAggregateException
would be fixed. I'm currently manually unwrappingAggregateException
before throwing from a synchronous entry point. It's a bit silly.