Skip to content

Commit

Permalink
Merge branch 'fix-aspnetcoreserver-exception-leak' of https://github.…
Browse files Browse the repository at this point in the history
…com/duncanbrown/aws-lambda-dotnet into duncanbrown-fix-aspnetcoreserver-exception-leak
  • Loading branch information
normj committed Feb 12, 2023
2 parents c43411f + 3f49f78 commit 0ca6732
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ public void RegisterResponseContentEncodingForContentEncoding(string contentEnco
_responseContentEncodingForContentEncoding[contentEncoding] = encoding;
}

/// <summary>
/// If true, information about unhandled exceptions thrown during request processing
/// will be included in the HTTP response.
/// Defaults to false
/// </summary>
public bool IncludeUnhandledExceptionDetailInResponse { get; set; }


/// <summary>
/// Method to initialize the web builder before starting the web host. In a typical Web API this is similar to the main function.
Expand Down Expand Up @@ -535,7 +542,7 @@ protected async Task<TRESPONSE> ProcessRequest(ILambdaContext lambdaContext, obj
}
var response = this.MarshallResponse(features, lambdaContext, defaultStatusCode);

if (ex != null)
if (ex != null && IncludeUnhandledExceptionDetailInResponse)
{
InternalCustomResponseExceptionHandling(response, lambdaContext, ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,26 @@ public async Task TestDefaultResponseErrorCode()
}

[Theory]
[InlineData("values-get-aggregateerror-httpapi-v2-request.json", "AggregateException")]
[InlineData("values-get-typeloaderror-httpapi-v2-request.json", "ReflectionTypeLoadException")]
public async Task TestEnhancedExceptions(string requestFileName, string expectedExceptionType)
[InlineData("values-get-aggregateerror-httpapi-v2-request.json", "AggregateException", true)]
[InlineData("values-get-typeloaderror-httpapi-v2-request.json", "ReflectionTypeLoadException", true)]
[InlineData("values-get-aggregateerror-httpapi-v2-request.json", "AggregateException", false)]
[InlineData("values-get-typeloaderror-httpapi-v2-request.json", "ReflectionTypeLoadException", false)]
public async Task TestEnhancedExceptions(string requestFileName, string expectedExceptionType, bool configureApiToReturnExceptionDetail)
{
var response = await this.InvokeAPIGatewayRequest(requestFileName);
var response = await this.InvokeAPIGatewayRequest(requestFileName, configureApiToReturnExceptionDetail);

Assert.Equal(500, response.StatusCode);
Assert.Equal(string.Empty, response.Body);
if (configureApiToReturnExceptionDetail)
{
Assert.True(response.Headers.ContainsKey("ErrorType"));
Assert.Equal(expectedExceptionType, response.Headers["ErrorType"]);
}
else
{
Assert.False(response.Headers.ContainsKey("ErrorType"));
}
}

[Fact]
public async Task TestGettingSwaggerDefinition()
Expand Down Expand Up @@ -258,19 +267,21 @@ public async Task TestTraceIdSetFromLambdaContext()
}
}

private async Task<APIGatewayHttpApiV2ProxyResponse> InvokeAPIGatewayRequest(string fileName)
private async Task<APIGatewayHttpApiV2ProxyResponse> InvokeAPIGatewayRequest(string fileName, bool configureApiToReturnExceptionDetail = false)
{
return await InvokeAPIGatewayRequestWithContent(new TestLambdaContext(), GetRequestContent(fileName));
return await InvokeAPIGatewayRequestWithContent(new TestLambdaContext(), GetRequestContent(fileName), configureApiToReturnExceptionDetail);
}

private async Task<APIGatewayHttpApiV2ProxyResponse> InvokeAPIGatewayRequest(TestLambdaContext context, string fileName)
private async Task<APIGatewayHttpApiV2ProxyResponse> InvokeAPIGatewayRequest(TestLambdaContext context, string fileName, bool configureApiToReturnExceptionDetail = false)
{
return await InvokeAPIGatewayRequestWithContent(context, GetRequestContent(fileName));
return await InvokeAPIGatewayRequestWithContent(context, GetRequestContent(fileName), configureApiToReturnExceptionDetail);
}

private async Task<APIGatewayHttpApiV2ProxyResponse> InvokeAPIGatewayRequestWithContent(TestLambdaContext context, string requestContent)
private async Task<APIGatewayHttpApiV2ProxyResponse> InvokeAPIGatewayRequestWithContent(TestLambdaContext context, string requestContent, bool configureApiToReturnExceptionDetail = false)
{
var lambdaFunction = new TestWebApp.HttpV2LambdaFunction();
if (configureApiToReturnExceptionDetail)
lambdaFunction.IncludeUnhandledExceptionDetailInResponse = true;
var requestStream = new MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(requestContent));
var request = new Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer().Deserialize<APIGatewayHttpApiV2ProxyRequest>(requestStream);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,26 @@ public async Task TestDefaultResponseErrorCode()
}

[Theory]
[InlineData("values-get-aggregateerror-apigateway-request.json", "AggregateException")]
[InlineData("values-get-typeloaderror-apigateway-request.json", "ReflectionTypeLoadException")]
public async Task TestEnhancedExceptions(string requestFileName, string expectedExceptionType)
[InlineData("values-get-aggregateerror-apigateway-request.json", "AggregateException", true)]
[InlineData("values-get-typeloaderror-apigateway-request.json", "ReflectionTypeLoadException", true)]
[InlineData("values-get-aggregateerror-apigateway-request.json", "AggregateException", false)]
[InlineData("values-get-typeloaderror-apigateway-request.json", "ReflectionTypeLoadException", false)]
public async Task TestEnhancedExceptions(string requestFileName, string expectedExceptionType, bool configureApiToReturnExceptionDetail)
{
var response = await this.InvokeAPIGatewayRequest(requestFileName);
var response = await this.InvokeAPIGatewayRequest(requestFileName, configureApiToReturnExceptionDetail);

Assert.Equal(500, response.StatusCode);
Assert.Equal(string.Empty, response.Body);
if (configureApiToReturnExceptionDetail)
{
Assert.True(response.MultiValueHeaders.ContainsKey("ErrorType"));
Assert.Equal(expectedExceptionType, response.MultiValueHeaders["ErrorType"][0]);
}
else
{
Assert.False(response.MultiValueHeaders.ContainsKey("ErrorType"));
}
}

[Fact]
public async Task TestGettingSwaggerDefinition()
Expand Down Expand Up @@ -442,19 +451,21 @@ public void EnsureTraceIdStaysTheSame()
Assert.Equal(traceId1, traceId2);
}

private async Task<APIGatewayProxyResponse> InvokeAPIGatewayRequest(string fileName)
private async Task<APIGatewayProxyResponse> InvokeAPIGatewayRequest(string fileName, bool configureApiToReturnExceptionDetail = false)
{
return await InvokeAPIGatewayRequest(new TestLambdaContext(), fileName);
return await InvokeAPIGatewayRequest(new TestLambdaContext(), fileName, configureApiToReturnExceptionDetail);
}

private async Task<APIGatewayProxyResponse> InvokeAPIGatewayRequest(TestLambdaContext context, string fileName)
private async Task<APIGatewayProxyResponse> InvokeAPIGatewayRequest(TestLambdaContext context, string fileName, bool configureApiToReturnExceptionDetail = false)
{
return await InvokeAPIGatewayRequestWithContent(context, GetRequestContent(fileName));
return await InvokeAPIGatewayRequestWithContent(context, GetRequestContent(fileName), configureApiToReturnExceptionDetail);
}

private async Task<APIGatewayProxyResponse> InvokeAPIGatewayRequestWithContent(TestLambdaContext context, string requestContent)
private async Task<APIGatewayProxyResponse> InvokeAPIGatewayRequestWithContent(TestLambdaContext context, string requestContent, bool configureApiToReturnExceptionDetail = false)
{
var lambdaFunction = new ApiGatewayLambdaFunction();
if (configureApiToReturnExceptionDetail)
lambdaFunction.IncludeUnhandledExceptionDetailInResponse = true;
var requestStream = new MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(requestContent));
var request = new Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer().Deserialize<APIGatewayProxyRequest>(requestStream);

Expand Down

0 comments on commit 0ca6732

Please sign in to comment.