# DRF Standardized Errors
Standardize your [DRF](https://www.django-rest-framework.org/) API error responses.
[![Read the Docs](https://img.shields.io/readthedocs/drf-error-handler)](https://drf-error-handler.readthedocs.io/en/latest/)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/korchizhinskiy/drf-error-handler/tests.yml?branch=main&label=Tests&logo=GitHub)](https://github.com/korchizhinskiy/drf-error-handler/actions/workflows/tests.yml)
[![codecov](https://codecov.io/gh/korchizhinskiy/drf-error-handler/branch/main/graph/badge.svg?token=JXTTT1KVBR)](https://codecov.io/gh/korchizhinskiy/drf-error-handler)
[![PyPI](https://img.shields.io/pypi/v/drf-error-handler)](https://pypi.org/project/drf-error-handler/)
[![PyPI - License](https://img.shields.io/pypi/l/drf-error-handler)](https://github.com/korchizhinskiy/drf-error-handler/blob/main/LICENSE)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
By default, the package will convert API error responses (4xx) to the following standardized format:
```json
{
"type": "validation_error",
"errors": [
{
"detail": "This field is required.",
"attr": "name"
},
{
"detail": "Ensure this value has at most 100 characters.",
"attr": "title",
"b_code": 10000
}
]
}
```
```json
{
"type": "client_error",
"errors": [
{
"detail": "Incorrect authentication credentials.",
"attr": null,
"b_code": 11111
}
]
}
```
## Features
- Highly customizable: gives you flexibility to define your own standardized error responses and override
specific aspects the exception handling process without having to rewrite everything.
- Supports nested serializers and ListSerializer errors
- Plays nicely with error monitoring tools (like Sentry, ...)
## Requirements
- python >= 3.8
- Django >= 3.2
- DRF >= 3.12
## Quickstart
Install with `pip`
```shell
pip install drf-error-handler
```
Add drf-error-handler to your installed apps
```python
INSTALLED_APPS = [
# other apps
"drf_error_handler",
]
```
Register the exception handler
```python
REST_FRAMEWORK = {
# other settings
"EXCEPTION_HANDLER": "drf_error_handler.handler.exception_handler"
}
```
Then you may override something a few settings for package
```python
DRF_ERROR_HANDLER = {
"EXCEPTION_RESPONSE_BUSINESS_ATTRIBUTE": "b_code"
}
```
This settings define, which attribute will be viewed in response body for business code.
But after that, all exception classes must containt an attribute with name, which you override in `EXCEPTION_RESPONSE_BUSINESS_ATTRIBUTE` settings ("b_code" by default).
For standart DRF Exceptions defined business code in settings.
```python
DRF_ERROR_HANDLER = {
"VALIDATION_ERROR_BUSINESS_STATUS_CODE": 1001,
"PARSE_ERROR_BUSINESS_STATUS_CODE": 1002,
"AUTHENTICATION_FAILED_BUSINESS_STATUS_CODE": 1003,
"NOT_AUTHENTICATION_BUSINESS_STATUS_CODE": 1004,
"PERMISSION_DENIED_BUSINESS_STATUS_CODE": 1005,
"NOT_FOUND_BUSINESS_STATUS_CODE": 1006,
"METHOD_NOT_ALLOWED_BUSINESS_STATUS_CODE": 1007,
"NOT_ACCEPTABLE_BUSINESS_STATUS_CODE": 1008,
"UNSUPPORTED_MEDIA_TYPE_BUSINESS_STATUS_CODE": 1009,
"THROTTLED_BUSINESS_STATUS_CODE": 1010
}
```
This codes will view for standart DRF and Django exceptions after handle by ErrorHandler in response body.
For create custom exception class, you should do that:
1. Create exception class with inherit from `rest_framework.exceptions.APIException`
```python
from rest_framework.exceptions import APIException
class CustomException(APIException):
status_code = status.HTTP_400_BAD_REQUEST
default_detail = 'You can\'t place an order at this time.'
b_code = 1011
```
You must define b_code (or overriding attribute) in exception class.
2. Raise custom exception.
```python
def view(request):
...
raise CustomException
```
3. And Error Handler process this exception and return valid response.
```json
{
"type": "client_error",
"errors": [
{
"detail": "You can't place an order at this time.",
"attr": null,
"b_code": 1011
}
]
}
```
### Notes
- This package is a DRF exception handler, so it standardizes errors that reach a DRF API view. That means it cannot
handle errors that happen at the middleware level for example. To handle those as well, you can customize
the necessary [django error views](https://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views).
You can find more about that in [this issue](https://github.com/korchizhinskiy/drf-error-handler/issues/44).
## Integration with DRF spectacular
If you plan to use [drf-spectacular](https://github.com/tfranzel/drf-spectacular) to generate an OpenAPI 3 schema,
install with `pip install drf-error-handler[openapi]`. After that, check the [doc page](https://drf-error-handler.readthedocs.io/en/latest/openapi.html)
for configuring the integration.
## Links
- Documentation: https://drf-error-handler.readthedocs.io/en/latest/
- Changelog: https://github.com/korchizhinskiy/drf-error-handler/releases
- Code & issues: https://github.com/korchizhinskiy/drf-error-handler
- PyPI: https://pypi.org/project/drf-error-handler/
## License
This project is [MIT licensed](LICENSE).
Raw data
{
"_id": null,
"home_page": null,
"name": "drf-error-handler",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "standardized errors, errors formatter, django rest framework, exception handler",
"author": "Ghazi Abbassi, Nazar Korchizhinskiy",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/64/dc/5926c9ac3a63f611a357e70b4e7601df7708de753ace9c956d9872c37cb7/drf_error_handler-0.15.1.tar.gz",
"platform": null,
"description": "# DRF Standardized Errors\n\nStandardize your [DRF](https://www.django-rest-framework.org/) API error responses.\n\n[![Read the Docs](https://img.shields.io/readthedocs/drf-error-handler)](https://drf-error-handler.readthedocs.io/en/latest/)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/korchizhinskiy/drf-error-handler/tests.yml?branch=main&label=Tests&logo=GitHub)](https://github.com/korchizhinskiy/drf-error-handler/actions/workflows/tests.yml)\n[![codecov](https://codecov.io/gh/korchizhinskiy/drf-error-handler/branch/main/graph/badge.svg?token=JXTTT1KVBR)](https://codecov.io/gh/korchizhinskiy/drf-error-handler)\n[![PyPI](https://img.shields.io/pypi/v/drf-error-handler)](https://pypi.org/project/drf-error-handler/)\n[![PyPI - License](https://img.shields.io/pypi/l/drf-error-handler)](https://github.com/korchizhinskiy/drf-error-handler/blob/main/LICENSE)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nBy default, the package will convert API error responses (4xx) to the following standardized format:\n```json\n{\n \"type\": \"validation_error\",\n \"errors\": [\n {\n \"detail\": \"This field is required.\",\n \"attr\": \"name\"\n },\n {\n \"detail\": \"Ensure this value has at most 100 characters.\",\n \"attr\": \"title\",\n \"b_code\": 10000\n }\n ]\n}\n```\n```json\n{\n \"type\": \"client_error\",\n \"errors\": [\n {\n \"detail\": \"Incorrect authentication credentials.\",\n \"attr\": null,\n \"b_code\": 11111\n }\n ]\n}\n```\n\n\n## Features\n\n- Highly customizable: gives you flexibility to define your own standardized error responses and override\nspecific aspects the exception handling process without having to rewrite everything.\n- Supports nested serializers and ListSerializer errors\n- Plays nicely with error monitoring tools (like Sentry, ...)\n\n\n## Requirements\n\n- python >= 3.8\n- Django >= 3.2\n- DRF >= 3.12\n\n\n## Quickstart\n\nInstall with `pip`\n```shell\npip install drf-error-handler\n```\n\nAdd drf-error-handler to your installed apps\n```python\nINSTALLED_APPS = [\n # other apps\n \"drf_error_handler\",\n]\n```\n\nRegister the exception handler\n```python\nREST_FRAMEWORK = {\n # other settings\n \"EXCEPTION_HANDLER\": \"drf_error_handler.handler.exception_handler\"\n}\n```\nThen you may override something a few settings for package\n\n```python\nDRF_ERROR_HANDLER = {\n \"EXCEPTION_RESPONSE_BUSINESS_ATTRIBUTE\": \"b_code\"\n}\n```\nThis settings define, which attribute will be viewed in response body for business code.\nBut after that, all exception classes must containt an attribute with name, which you override in `EXCEPTION_RESPONSE_BUSINESS_ATTRIBUTE` settings (\"b_code\" by default).\n\nFor standart DRF Exceptions defined business code in settings.\n```python\nDRF_ERROR_HANDLER = {\n \"VALIDATION_ERROR_BUSINESS_STATUS_CODE\": 1001,\n \"PARSE_ERROR_BUSINESS_STATUS_CODE\": 1002,\n \"AUTHENTICATION_FAILED_BUSINESS_STATUS_CODE\": 1003,\n \"NOT_AUTHENTICATION_BUSINESS_STATUS_CODE\": 1004,\n \"PERMISSION_DENIED_BUSINESS_STATUS_CODE\": 1005,\n \"NOT_FOUND_BUSINESS_STATUS_CODE\": 1006,\n \"METHOD_NOT_ALLOWED_BUSINESS_STATUS_CODE\": 1007,\n \"NOT_ACCEPTABLE_BUSINESS_STATUS_CODE\": 1008,\n \"UNSUPPORTED_MEDIA_TYPE_BUSINESS_STATUS_CODE\": 1009,\n \"THROTTLED_BUSINESS_STATUS_CODE\": 1010\n}\n```\nThis codes will view for standart DRF and Django exceptions after handle by ErrorHandler in response body.\n\nFor create custom exception class, you should do that:\n1. Create exception class with inherit from `rest_framework.exceptions.APIException`\n```python\nfrom rest_framework.exceptions import APIException\n\nclass CustomException(APIException):\n status_code = status.HTTP_400_BAD_REQUEST\n default_detail = 'You can\\'t place an order at this time.'\n b_code = 1011\n\n```\nYou must define b_code (or overriding attribute) in exception class.\n\n2. Raise custom exception.\n```python\ndef view(request):\n ...\n raise CustomException\n```\n\n3. And Error Handler process this exception and return valid response.\n\n```json\n{\n \"type\": \"client_error\",\n \"errors\": [\n {\n \"detail\": \"You can't place an order at this time.\",\n \"attr\": null,\n \"b_code\": 1011\n }\n ]\n}\n```\n\n\n### Notes\n- This package is a DRF exception handler, so it standardizes errors that reach a DRF API view. That means it cannot\nhandle errors that happen at the middleware level for example. To handle those as well, you can customize\nthe necessary [django error views](https://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views).\nYou can find more about that in [this issue](https://github.com/korchizhinskiy/drf-error-handler/issues/44).\n\n## Integration with DRF spectacular\nIf you plan to use [drf-spectacular](https://github.com/tfranzel/drf-spectacular) to generate an OpenAPI 3 schema,\ninstall with `pip install drf-error-handler[openapi]`. After that, check the [doc page](https://drf-error-handler.readthedocs.io/en/latest/openapi.html)\nfor configuring the integration.\n\n## Links\n\n- Documentation: https://drf-error-handler.readthedocs.io/en/latest/\n- Changelog: https://github.com/korchizhinskiy/drf-error-handler/releases\n- Code & issues: https://github.com/korchizhinskiy/drf-error-handler\n- PyPI: https://pypi.org/project/drf-error-handler/\n\n\n## License\n\nThis project is [MIT licensed](LICENSE).\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Standardize your API error responses.",
"version": "0.15.1",
"project_urls": {
"Changelog": "https://github.com/korchizhinskiy/drf-error-handler/releases",
"Code": "https://github.com/korchizhinskiy/drf-error-handler",
"Documentation": "https://drf-error-handler.readthedocs.io/en/latest/",
"Homepage": "https://github.com/korchizhinskiy/drf-error-handler",
"Issues": "https://github.com/korchizhinskiy/drf-error-handler/issues"
},
"split_keywords": [
"standardized errors",
" errors formatter",
" django rest framework",
" exception handler"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "47b1a8114038ba8235997ef4e9cdc27834cd8a15bfd86864b5e7368f515c6894",
"md5": "6e75c38a92a68fd1a8d445b4bf3d4c7c",
"sha256": "ac553da9c807168f90f55361dc2418957248368cdb91111703a1851fef235cde"
},
"downloads": -1,
"filename": "drf_error_handler-0.15.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6e75c38a92a68fd1a8d445b4bf3d4c7c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 26721,
"upload_time": "2024-04-15T05:27:40",
"upload_time_iso_8601": "2024-04-15T05:27:40.634379Z",
"url": "https://files.pythonhosted.org/packages/47/b1/a8114038ba8235997ef4e9cdc27834cd8a15bfd86864b5e7368f515c6894/drf_error_handler-0.15.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "64dc5926c9ac3a63f611a357e70b4e7601df7708de753ace9c956d9872c37cb7",
"md5": "e87b4538e2daa5080ffadd56ec2b6fda",
"sha256": "b19fc0063d8ffaacaa8eb05aa1cf1d5095461e0d8add72e22e3655f535f85d34"
},
"downloads": -1,
"filename": "drf_error_handler-0.15.1.tar.gz",
"has_sig": false,
"md5_digest": "e87b4538e2daa5080ffadd56ec2b6fda",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 23945,
"upload_time": "2024-04-15T05:27:42",
"upload_time_iso_8601": "2024-04-15T05:27:42.572870Z",
"url": "https://files.pythonhosted.org/packages/64/dc/5926c9ac3a63f611a357e70b4e7601df7708de753ace9c956d9872c37cb7/drf_error_handler-0.15.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-15 05:27:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "korchizhinskiy",
"github_project": "drf-error-handler",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "drf-error-handler"
}