Standardized and easy-to-parse API error responses for DRF.
Project description
DRF Exceptions Hog
Standardized and easy-to-parse API error responses for Django REST Framework.
After reusing similar code in multiple projects, we realized this might actually help others. The problem we're trying to solve is that DRF exceptions tend to vary in format and therefore require complex parsing logic on the frontend, which generally needs to be implemented in more than one language or framework. This simple package standardizes the exception responses to simplify the parsing logic on the frontend and enable developers to provide clear errors to their users (instead of the cryptic or even shady-looking parsing errors). This package is inspired on the way Stripe API handles errors. See an example below.
You will get predictable responses like these:
// Example 1
{
"type": "validation_error",
"code": "required",
"detail": "This field is required.",
"attr": "name"
}
// Example 2
{
"type": "authentication_error",
"code": "permission_denied",
"detail": "You do not have permission to perform this operation.",
"attr": null
}
instead of these:
// Example 1
{
"name": ["This field is required."]
}
// Example 2
{
"detail": "You do not have permission to perform this operation."
}
Note: Currently we only support JSON responses. If you'd like us to support a different response format, please open an issue or a PR (see Contributing)
🔌 Usage
To start using DRF Exceptions Hog please follow these instructions:
Install the package with pip
pip install drf-exceptions-hog
Update your DRF configuration on your settings.py
.
REST_FRAMEWORK={
"EXCEPTION_HANDLER": "exceptions_hog.exception_handler",
}
Optionally set additional configuration for the package.
EXCEPTIONS_HOG = {
"EXCEPTION_REPORTING": "exceptions_hog.handler.exception_reporter",
"ENABLE_IN_DEBUG": False,
"NESTED_KEY_SEPARATOR": "__",
"SUPPORT_MULTIPLE_EXCEPTIONS": False,
}
EXCEPTION_REPORTING
: specify a method to call after an exception occurs. Particularly useful to report errors (e.g. through Sentry, NewRelic, ...). Default:exceptions_hog.handler.exception_reporter
ENABLE_IN_DEBUG
: whether exceptions-hog should run whenDEBUG = 1
. It's useful to turn this off in debugging to get full error stack traces when developing. Defaut:False
.NESTED_KEY_SEPARATOR
: customize the separator used for obtaining theattr
name if the exception comes from nested objects (e.g. nested serializers). Default:__
.SUPPORT_MULTIPLE_EXCEPTIONS
: whether exceptions-hog should return all exceptions in an error response. Useful particularly in form and serializer validation where multiple input exceptions can occur.
📑 Documentation
We're working on more comprehensive documentation. Feel free to open a PR to contribute to this. In the meantime, you will find the most relevant information for this package here.
Response structure
All responses handled by DRF Exceptions Hog have the following format:
{
"type": "server_error",
"code": "server_error",
"detail": "Something went wrong.",
"attr": null,
"list": null
}
where:
type
entails the high-level grouping of the type error returned (See Error Types).code
is a machine-friendly error code specific for this type of error (e.g.permission_denied
,method_not_allowed
,required
)detail
will contain human-friendly information on the error (e.g. "This field is required.", "Authentication credentials were not provided.").- For security reasons (mainly to avoid leaking sensitive information) this attribute will return a generic error message for unhandled server exceptions, like an
ImportError
. - If you use Django localization, all our exception detail messages support using multiple languages.
- For security reasons (mainly to avoid leaking sensitive information) this attribute will return a generic error message for unhandled server exceptions, like an
attr
will contain the name of the attribute to which the exception is related. Relevant mostly forvalidation_error
s.list
will only be returned when multiple exceptions are enabled and the exception contains multiple exceptions (i.e.type = multiple
).extra
is an extra attribute you can set on an exception to pass through extra content, normally in dict form.
Multiple exceptions
There are some cases when handling multiple exceptions in a single response can be helpful. For instance, if you have a form with multiple fields, each field can have their own validations, and a user could benefit from knowing everything that is wrong in a single pass. You can enable multiple exception support by setting the SUPPORT_MULTIPLE_EXCEPTIONS
setting to True
. When it's enabled, if multiple exceptions are raised (e.g. by a serializer), you will receive a response like this:
{
"type": "multiple",
"code": "multiple",
"detail": "Multiple exceptions ocurred. Please check list for details.",
"attr": null,
"list": [
{
"type": "validation_error",
"code": "required",
"detail": "This field is required.",
"attr": "email"
},
{
"type": "validation_error",
"code": "unsafe_password",
"detail": "This password is unsafe.",
"attr": "password"
}
]
}
Error types
Our package introduces the following general error types (but feel free to add custom ones):
authentication_error
indicates there is an authentication-related problem with the request (e.g. no authentication credentials provided, invalid or expired credentials provided, credentials have insufficient privileges, etc.)invalid_request
indicates a general issue with the request that must be fixed by the client, excluding validation errors (e.g. request has an invalid media type format, request is malformed, etc.)multiple
indicates multiple exceptions ocurred (only if enabled). See multiple exceptions for details.server_error
indicates a generic internal server error that needs to be addressed on the server.throttled_error
indicates the request is throttled or rate limited and must be retried by the client at a later time.validation_error
indicates the request has not passed validation and must be fixed by the client (e.g. a required attribute was not provided, an incorrect data type was passed for an attribute, etc.)
🤝 Contributing
Want to help move this project forward? Read our CONTRIBUTING.md.
👩💻 Development
To run a local copy of the package for development, please follow these instructions:
-
Clone the repository.
-
[Optional]. Install and activate a virtual enviroment. Example:
python3 -m venv env && source env/bin/activate
-
Install the project dependencies and the test dependencies.
python setup.py develop pip install -r requirements-test.txt
-
Run the tests to make sure everything is working as expected.
python runtests.py
-
Start coding!
🧱 Requirements
- This package requires at least Python 3.7 & Django 3.1
- Supported Python versions: 3.7.x, 3.8.x & 3.9.x
- Supported Django versions: 3.1.x & 3.2.x
👨⚖️ License
We ♥ Open Source! This repository is MIT licensed by PostHog. Full license here.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file drf-exceptions-hog-0.4.0.tar.gz
.
File metadata
- Download URL: drf-exceptions-hog-0.4.0.tar.gz
- Upload date:
- Size: 13.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d7b4ec771c7a1dc58409746e09373af50b5d4029fa4fdfa6d0b597625ed9cdab |
|
MD5 | c8f3064704d527883fa8b01c71534a28 |
|
BLAKE2b-256 | dc92c87b3e5c08c9cc5c542c17fa0fdde94f05106b596a6645d108c3ea22b930 |
File details
Details for the file drf_exceptions_hog-0.4.0-py3-none-any.whl
.
File metadata
- Download URL: drf_exceptions_hog-0.4.0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12dc820012f04be86bc8195ba06a09ab6c451fb21ac9d7b3067681f182057d41 |
|
MD5 | 5422b00cd8d0f89679d55e7f23a7f200 |
|
BLAKE2b-256 | b247695a351c0ceae378905c824f2a1b7b465ca076a73d6fd502cd2ecae3d9d1 |