vitalik / django-ninja

💨 Fast, Async-ready, Openapi, type hints based framework for building APIs
https://django-ninja.dev
MIT License
7.19k stars 425 forks source link

Easy way to change behavior of `BodyModel`? #1265

Open jmduke opened 2 months ago

jmduke commented 2 months ago

Hello! Thank you for django-ninja: we use it to power Buttondown's internal and external APIs, and it's been a delight.

I recently received a report from a user trying to integrate — they received the following error code:

{"detail":"Cannot parse request body"}

They needed to JSON-serialize their body, but I was curious as to where that error was propagated/populated — and found this BodyModel param (https://github.com/vitalik/django-ninja/blob/b1ecd36e1c9b096ca68ca458cce687593d6173af/ninja/params/models.py#L123).

I'd really like to be able to overwrite this error with something more actionable for users ("You passed in a FormData object, but we expected a JSON payload", that sort of thing.) Is there an easy way to configure this, or is my best option to monkey-patch get_request_data?

(Notably, that method discards the exception entirely, which is unfortunate — being able to just supply a string through the Exception, while not ideal, would still be useful.)

lapinvert commented 2 months ago

I guess you just need to define a custom exception handler for this error. Have you tried it?

from json import JSONDecodeError
# (...)

api = NinjaAPI()
api.add_exception_handler(JSONDecodeError, json_decode_error_handler)
jmduke commented 2 months ago

@lapinvert Ah, good call — that should unblock me. Still, it feels a little bit aggressive to the extent that if I have other JSONDecodeErrors in the call-chain I'd want to potentially 500 as opposed to returning an incorrect error. (Which I could then avoid by introspecting within the exception handler, but that feels very kludgy.)