AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

Invalid JSON returned 500 when 400 is expected

Open sherlock1982 opened this issue 1 year ago • 1 comments

Assemblies affected Microsoft.AspNetCore.OData 9.1.1

Describe the bug A clear and concise description of what the bug is.

Reproduce steps Send invalid JSON to OData endpoint

Request/Response

POST /something HTTP/2
...
{"routes":{"Id":34,"Routes":[{"DID":"17772229192","TrunkId":40,"DisplayName":"~!@#$%^&*()_+{}[]:\":|;'\<>?,./"}]}}
=>
HTTP/2 500 Internal Server Error

2024/11/27 09:35:36.762|0020|Erro| [Microsoft.AspNetCore.Server.Kestrel] Connection id "0HN8EN6DSSIMU", Request id "0HN8EN6DSSIMU:00000002": An unhandled exception was thrown by the application.
Microsoft.OData.ODataException: Invalid JSON. An unrecognized escape sequence '\<' was found in a JSON string value.
   at Microsoft.OData.Json.JsonReader.ParseStringPrimitiveValueAsync()
   at Microsoft.OData.Json.JsonReader.GetValueAsync()
   at Microsoft.OData.Json.BufferingJsonReader.ReadInternalAsync()
   at Microsoft.OData.Json.ReorderingJsonReader.ReadPropertyNameAsync()
   at Microsoft.OData.Json.ReorderingJsonReader.ProcessObjectValueAsync()
   at Microsoft.OData.Json.BufferingJsonReader.ReadNextAndCheckForInStreamErrorAsync()
   at Microsoft.OData.Json.BufferingJsonReader.ReadInternalAsync()
   at Microsoft.OData.Json.ODataJsonDeserializer.ReadPayloadStartImplementationAsync(ODataPayloadKind payloadKind, PropertyAndAnnotationCollector propertyAndAnnotationCollector, Boolean isReadingNestedPayload, Boolean allowEmptyPayload)
   at Microsoft.OData.Json.ODataJsonDeserializer.ReadPayloadStartAsync(ODataPayloadKind payloadKind, PropertyAndAnnotationCollector propertyAndAnnotationCollector, Boolean isReadingNestedPayload, Boolean allowEmptyPayload, IEdmNavigatio>
   at Microsoft.OData.Json.ODataJsonParameterReader.ReadAtStartImplementationAsync()
   at Microsoft.OData.ODataParameterReaderCoreAsync.ReadAsynchronously()
   at Microsoft.OData.ODataParameterReaderCore.InterceptExceptionAsync[TResult](Func`2 action)
   at Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataActionPayloadDeserializer.ReadAsync(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
   at Microsoft.AspNetCore.OData.Formatter.ODataBodyModelBinder.ReadODataBodyAsync(ModelBindingContext bindingContext)
   at Microsoft.AspNetCore.OData.Formatter.ODataBodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
   at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinder.BindModelAsync(ModelBindingContext bindingContext)
   at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object >
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

Expected behavior Return 400

sherlock1982 avatar Nov 27 '24 08:11 sherlock1982

It disappoints me a bit that OData has so many of these cases of poor error handling that either result in a 500, or do the opposite and ignore exceptions that should be 500 and return 200 instead...

It's honestly one of the things (out of a few) that makes the framework look unprofessional/unpolished.

julealgon avatar Nov 27 '24 13:11 julealgon