mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Adds a custom exception handler for DRF
- Handles common exceptions not captured by DRF - Returns exeption data as a JSON object
This commit is contained in:
parent
ea2fb76a29
commit
1488a0e72f
80
InvenTree/InvenTree/exceptions.py
Normal file
80
InvenTree/InvenTree/exceptions.py
Normal file
@ -0,0 +1,80 @@
|
||||
"""
|
||||
Custom exception handling for the DRF API
|
||||
"""
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from django.db.utils import OperationalError, ProgrammingError, IntegrityError
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from error_report.models import Error
|
||||
|
||||
from rest_framework.exceptions import ValidationError as DRFValidationError
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import serializers
|
||||
import rest_framework.views as drfviews
|
||||
|
||||
|
||||
def exception_handler(exc, context):
|
||||
"""
|
||||
Custom exception handler for DRF framework.
|
||||
Ref: https://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-handling
|
||||
|
||||
Catches any errors not natively handled by DRF, and re-throws as an error DRF can handle
|
||||
"""
|
||||
|
||||
response = None
|
||||
|
||||
# Catch any django validation error, and re-throw a DRF validation error
|
||||
if isinstance(exc, DjangoValidationError):
|
||||
exc = DRFValidationError(detail=serializers.as_serializer_error(exc))
|
||||
|
||||
# Exceptions we will manually check for here
|
||||
handled_exceptions = [
|
||||
IntegrityError,
|
||||
OperationalError,
|
||||
ProgrammingError,
|
||||
ValueError,
|
||||
TypeError,
|
||||
NameError,
|
||||
]
|
||||
|
||||
if any([isinstance(exc, err_type) for err_type in handled_exceptions]):
|
||||
|
||||
if settings.DEBUG:
|
||||
error_detail = str(exc)
|
||||
else:
|
||||
error_detail = _("Error details can be found in the admin panel")
|
||||
|
||||
response_data = {
|
||||
'error': type(exc).__name__,
|
||||
'error_class': str(type(exc)),
|
||||
'detail': error_detail,
|
||||
'path': context['request'].path,
|
||||
'status_code': 500,
|
||||
}
|
||||
|
||||
response = Response(response_data, status=500)
|
||||
|
||||
# Log the exception to the database, too
|
||||
Error.objects.create(
|
||||
kind="Unhandled DRF API Exception",
|
||||
info=str(type(exc)),
|
||||
data=str(exc),
|
||||
path=context['request'].path,
|
||||
)
|
||||
|
||||
else:
|
||||
# Fallback to the default DRF exception handler
|
||||
response = drfviews.exception_handler(exc, context)
|
||||
|
||||
if response is not None:
|
||||
# For an error response, include status code information
|
||||
response.data['status_code'] = response.status_code
|
||||
|
||||
return response
|
@ -353,7 +353,7 @@ TEMPLATES = [
|
||||
]
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
|
||||
'EXCEPTION_HANDLER': 'InvenTree.exceptions.exception_handler',
|
||||
'DATETIME_FORMAT': '%Y-%m-%d %H:%M',
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.BasicAuthentication',
|
||||
|
Loading…
Reference in New Issue
Block a user