Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AspNetCoreServer: make adding exception detail to http response opt-in #899

Merged
merged 1 commit into from
Feb 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,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 @@ -532,7 +539,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,16 +116,25 @@ 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);
Assert.True(response.Headers.ContainsKey("ErrorType"));
Assert.Equal(expectedExceptionType, response.Headers["ErrorType"]);
if (configureApiToReturnExceptionDetail)
{
Assert.True(response.Headers.ContainsKey("ErrorType"));
Assert.Equal(expectedExceptionType, response.Headers["ErrorType"]);
}
else
{
Assert.False(response.Headers.ContainsKey("ErrorType"));
}
}

[Fact]
Expand Down Expand Up @@ -235,19 +244,21 @@ public async Task TestMultipleCookie()
Assert.Equal("TestValue3", response.Body);
}

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)
{
return await InvokeAPIGatewayRequestWithContent(context, GetRequestContent(fileName));
}

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));
#if NETCOREAPP_2_1
var request = new Amazon.Lambda.Serialization.Json.JsonSerializer().Deserialize<APIGatewayHttpApiV2ProxyRequest>(requestStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,25 @@ 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);
Assert.True(response.MultiValueHeaders.ContainsKey("ErrorType"));
Assert.Equal(expectedExceptionType, response.MultiValueHeaders["ErrorType"][0]);
if (configureApiToReturnExceptionDetail)
{
Assert.True(response.MultiValueHeaders.ContainsKey("ErrorType"));
Assert.Equal(expectedExceptionType, response.MultiValueHeaders["ErrorType"][0]);
}
else
{
Assert.False(response.MultiValueHeaders.ContainsKey("ErrorType"));
}
}

[Fact]
Expand Down Expand Up @@ -416,19 +425,21 @@ public async Task TestRequestServicesAreAvailable()
Assert.Equal("Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope", response.Body);
}

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));
#if NETCOREAPP_2_1
var request = new Amazon.Lambda.Serialization.Json.JsonSerializer().Deserialize<APIGatewayProxyRequest>(requestStream);
Expand Down