... | ... | @@ -2,6 +2,13 @@ Django REST Framework has a few quirks that aren't immediately obvious that can |
|
|
|
|
|
Before continuing, please read the [Exceptions](https://www.django-rest-framework.org/api-guide/exceptions/) API Guide page on DRF's site.
|
|
|
|
|
|
Rules:
|
|
|
|
|
|
- Serializers and views must only raise subclasses of `rest_framework.exceptions.APIException`
|
|
|
- Always raise an exception, never manually return a `Response` with an error status code
|
|
|
- `ValidationError` must only be raised in the `validate` or `validate_<field>` methods of a serializer
|
|
|
- Assume messages will be displayed to the user!
|
|
|
|
|
|
## Serializers and views must only raise subclasses of `rest_framework.exceptions.APIException`
|
|
|
|
|
|
The only exceptions handled by DRF's exception handler are subclasses of `rest_framework.exceptions.APIException`, which means that when explicitly raising an exception in a serializer or view, it MUST be a subclass of `APIException`. If any other type of exception is raised it will not be handled by the DRF exception handler, and will instead result in a Django error page (when DEBUG is true).
|
... | ... | @@ -71,4 +78,21 @@ This one definitely took me the most time to realize, and it isn't necessarily a |
|
|
|
|
|
DRF's `ValidationError` is handled differently than the rest of the `APIException` subclasses. Rather than having a `detail: str` message body, it'll return a dict of errors related to either specific fields, or `non_field_errors` if not related to any specific field.
|
|
|
|
|
|
## Assume messages will be displayed to the user! |
|
|
\ No newline at end of file |
|
|
However! This is the part that the API Guide doesn't explain:
|
|
|
|
|
|
If you raise a validation error outside of a serializer's `validate` or `validate_<field>` functions, it'll simply return an array of error messages rather than a dict:
|
|
|
|
|
|
```python
|
|
|
def list(self, request):
|
|
|
raise exceptions.ValidationError("Something went wrong")
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
This is not ideal for the frontend, because it is the only time that an array is returned rather than a dictionary with the keys `detail`, `non_field_errors` or field names. This makes it so that every time the frontend tries to handle an error it must first check if the response body is an array and handle it entirely differently than other errors.
|
|
|
|
|
|
So, instead of raising `ValidationError` outside of the `validate` functions, something like a generic `exeptions.APIException` or `exceptions.ParseError` should be raised instead.
|
|
|
|
|
|
## Assume messages will be displayed to the user!
|
|
|
|
|
|
This isn't so much a rule as it is a reminder, error messages *will* be displayed to the user. Errors that are explicitly raised should be worded as if describing what happened to the user. Just something to keep in mind! |
|
|
\ No newline at end of file |