0

I encounter a very wierd error.

I have an Item with some properties that are JsonRequired.

When i try to call my route to get my Item when one property that is required is missing, my error is not automatically thrown as an error code 500 I get a 200 Ok instead.

Here is my route :

[HttpGet("{itemId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<Item>> GetItemByIdAsync(long installationId, Guid itemId)
    {
        return await _itemService.GetItemByIdAsync(installationId, itemId);
    }

Here is my Item class :

public class Item
{
    [JsonProperty("id")]
    [JsonRequired]
    public Guid Id { get; set; }

    [JsonProperty("name")]
    [JsonRequired]
    public string Name { get; set; }
}

And here is my middleware :

public async Task Invoke(HttpContext context)
{
        try
        {
            await _next(context);
        }
        catch (NotFoundException ex)
        {
            await HandleExceptionAsync(context, HttpStatusCode.NotFound, ex);
        }
        catch (UnauthorizedException ex)
        {
            await HandleExceptionAsync(context, HttpStatusCode.Unauthorized, ex, false);
        }
        catch (ConflictException ex)
        {
            await HandleExceptionAsync(context, HttpStatusCode.Conflict, ex);
        }
        catch (BadRequestException ex)
        {
            await HandleExceptionAsync(context, HttpStatusCode.BadRequest, ex);
        }
    }

private Task HandleExceptionAsync(HttpContext context, HttpStatusCode httpCode, Exception exception, bool displayException = true)
{
        _logger.LogError(exception, $"Exception catched in middleware: {exception.Message}.");

        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)httpCode;

        var payload = JsonConvert.SerializeObject(new ApiError(displayException ? exception.Message : string.Empty));

            return context.Response.WriteAsync(payload);
}

What I have tried : If I try to add this catch in the middleware

catch (Exception ex)
    {
        await HandleExceptionAsync(context, HttpStatusCode.InternalServerError, ex);
    }

There is still the same result I don't get a 500 error. I don't really understand why my response is not overrided to be a 500 error. Do you have any idea ?

Thanks a lot.

Xyluun
  • 288
  • 1
  • 2
  • 8

1 Answers1

1

Since you do not show your _itemService.GetItemByIdAsync.It works well when I test with below code which has an 500 error.

public async Task<ActionResult<Item>> GetItemByIdAsync()
    {
        string json = @"{
          'id': '2f5135a7-977c-4b26-a4e2-74b9e374a75e',
          'name': null,

        }";

        Item x = JsonConvert.DeserializeObject<Item>(json);//throw 500 error using your Item model
        return x;
    }

You could also use Required property for JsonProperty like

[JsonProperty("name", Required = Required.Always)] //could not be null       
public string Name { get; set; }

The definition for it is:

    //
// Summary:
//     Indicating whether a property is required.
public enum Required
{
    //
    // Summary:
    //     The property is not required. The default state.
    Default = 0,
    //
    // Summary:
    //     The property must be defined in JSON but can be a null value.
    AllowNull = 1,
    //
    // Summary:
    //     The property must be defined in JSON and cannot be a null value.
    Always = 2,
    //
    // Summary:
    //     The property is not required but it cannot be a null value.
    DisallowNull = 3
}
Ryan
  • 19,118
  • 10
  • 37
  • 53
  • Thanks for your reply. I will try what you are proposing. But I don't get any error in my _itemService.GetItemById it returns an Item with a property id filled and a name at null. – Xyluun Sep 05 '19 at 07:12