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

Inconsistent type for exceptionMessage (AutoWrapper 4.5) #133

Open
nwoolls opened this issue May 10, 2022 · 1 comment
Open

Inconsistent type for exceptionMessage (AutoWrapper 4.5) #133

nwoolls opened this issue May 10, 2022 · 1 comment

Comments

@nwoolls
Copy link

nwoolls commented May 10, 2022

Hi there. First of all, thanks for your time and project!

I am having an issue with the latest stable version of the library (4.5) running on .NET Core 6.0.

Specifically, under some circumstances the exceptionMessage JSON property is a string, and in some cases the exceptionMessage JSON property is an object. This poses issues when parsing the result, especially using C# where we expect to be able to map the property to a specific type.

You can reproduce this with the following steps.

From the command line:

dotnet --version
6.0.101
mkdir autowrapper-exceptionmessage-issue
cd autowrapper-exceptionmessage-issue/
dotnet new webapi
dotnet add package AutoWrapper.Core --version 4.5.0

Edit Program.cs and add:

var options = new AutoWrapperOptions
{
    IsDebug = app.Environment.IsDevelopment()
};
app.UseApiResponseAndExceptionWrapper(options);

Edit WeatherForecastController.cs and add:

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

[HttpPost]
public IActionResult Post(InputModel inputModel)
{
    if (inputModel.FirstName == "foo")
    {
        return StatusCode(StatusCodes.Status400BadRequest, "An error occurred - returning status code");
    }

    if (inputModel.FirstName == "bar")
    {
        throw new ApiException("An error occurred - throwing ApiException");
    }
    
    return StatusCode(StatusCodes.Status201Created);
}

Run the project.

The following are examples where exceptionMessage may either be an object or a string:

Example 1 - exceptionMessage is an object

curl -X 'POST' \
  'https://localhost:7284/WeatherForecast' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{}'
{
  "isError": true,
  "responseException": {
    "exceptionMessage": {
      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
      "title": "One or more validation errors occurred.",
      "status": 400,
      "traceId": "00-12ce2cc5118d85bf077d9d4f71342ef0-23dae6d83195f904-00",
      "errors": {
        "FirstName": [
          "The FirstName field is required."
        ]
      }
    }
  }
}

Example 2 - exceptionMessage is an object

curl -X 'POST' \
  'https://localhost:7284/WeatherForecast' \
  -H 'accept: */*' \
  -d '{
  "firstName": "string"
}'
{
  "isError": true,
  "responseException": {
    "exceptionMessage": {
      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
      "title": "Unsupported Media Type",
      "status": 415,
      "traceId": "00-bc5f37b0710ad9189d09f5de6cfdd981-59a78671fdb1671e-00"
    }
  }
}

Example 3 - exceptionMessage is a string

curl -X 'POST' \
  'https://localhost:7284/WeatherForecast' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "foo"
}'
{
  "isError": true,
  "responseException": {
    "exceptionMessage": "An error occurred - returning status code"
  }
}

Example 4 - exceptionMessage is a string

curl -X 'POST' \
  'https://localhost:7284/WeatherForecast' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "bar"
}'
{
  "isError": true,
  "responseException": {
    "exceptionMessage": "An error occurred - throwing ApiException"
  }
}

Any guidance on this would be very much appreciated. Thanks in advance!

@nwoolls nwoolls changed the title Inconsistent type for exceptionMessage Inconsistent type for exceptionMessage (AutoWrapper 4.5) May 10, 2022
@Varveyn
Copy link

Varveyn commented Aug 11, 2023

I've managed to workaround this issue in case of 400 Bad Request by using custom error model together with overriding the ApiBehaviorOptions.InvalidModelStateResponseFactory.

Something like this:

In Program.cs:

_ = builder.Services
    .Configure<ApiBehaviorOptions>(options => options
        .InvalidModelStateResponseFactory = CustomInvalidModelStateResponseFactory.OnActionExecuting);

In CustomInvalidModelStateResponseFactory.cs:

// trimmed for brevity
public static IActionResult OnActionExecuting(ActionContext context)
{
    // trimmed for brevity
    throw new ApiException(new GenericApiError
    {
        error_message = "Request model is invalid.",
        validation_errors = validationErrors,
    });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants