proudmonkey / AutoWrapper

A simple, yet customizable global exception handler and Http response wrapper for ASP.NET Core APIs.
MIT License
679 stars 82 forks source link

Status code not respected for ApiException (AutoWrapper 5.0) #134

Open nwoolls opened 2 years ago

nwoolls commented 2 years ago

Hi there. I am trying out AutoWrapper 5.0 in an attempt to work around the problem described in issue #133.

With AutoWrapper 5.0, I am running into the following problem: when passing in a status code (e.g. 400) to the ApiException constructor, the resulting JSON object indicates the status code is 500.

You can reproduce this with the following steps.

From the command line:

dotnet --version
6.0.101
mkdir autowrapper-apiexception-issue
cd autowrapper-apiexception-issue/
dotnet new webapi
dotnet add package AutoWrapper.Core --version 5.0.0-rc-03

Edit Program.cs and add:

public class InputModel
{
    [Required(AllowEmptyStrings = false)]
    public string? FirstName { get; set; }
}

[HttpPost]
public IActionResult Post(InputModel inputModel)
{
    if (inputModel.FirstName == "foo")
    {
        throw new ApiException("An error occurred - throwing ApiException", StatusCodes.Status400BadRequest);
    }

    if (inputModel.FirstName == "bar")
    {
        throw new ApiProblemDetailsException("An error occurred - throwing ApiProblemDetailsException", StatusCodes.Status400BadRequest);
    }

    return StatusCode(StatusCodes.Status201Created);
}

Run the project.

The following are examples where throwing exceptions may result in a status code of 500 or 400.

Example 1 - Status Code is 500

curl -X 'POST' \
  'https://localhost:7006/WeatherForecast' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "foo"
}'
{
  "isError": true,
  "errors": {
    "message": "An error occurred - throwing ApiException",
    "type": "ApiException",
    "source": "autowrapper-apiexception-issue",
    "raw": "   at autowrapper_apiexception_issue.Controllers.WeatherForecastController.Post(InputModel inputModel) in ..."
  },
  "validationErrors": null,
  "type": "https://httpstatuses.com/500",
  "title": "Internal Server Error",
  "status": 500,
  "detail": "An error occurred - throwing ApiException",
  "instance": "/WeatherForecast"
}

Example 2 - status code is 400

curl -X 'POST' \
  'https://localhost:7006/WeatherForecast' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "bar"
}'
{
  "isError": true,
  "errors": null,
  "validationErrors": null,
  "type": "https://httpstatuses.com/400",
  "title": "An error occurred - throwing ApiProblemDetailsException",
  "status": 400,
  "detail": null,
  "instance": "/WeatherForecast"
}

This may be by-design due to the new defaults in AutoWrapper 5.0, but some clarity on this would still be much appreciated.

andychin7777 commented 1 year ago

this seems to be an issue with 4.5 as well. e.g.

throw new ApiException("No User Found", statusCode: StatusCodes.Status400BadRequest);

will return 500 response regardless same as OP