better exception
This commit is contained in:
parent
b8a57a0ce4
commit
c227fda538
1 changed files with 53 additions and 9 deletions
|
|
@ -1,25 +1,49 @@
|
|||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from rest_framework.exceptions import APIException
|
||||
from rest_framework.views import exception_handler as drf_exception_handler
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def exception_handler(exc, context):
|
||||
logger.exception(exc)
|
||||
# پاسخ پیشفرض DRF را دریافت میکنیم
|
||||
response = drf_exception_handler(exc, context)
|
||||
|
||||
if response is not None:
|
||||
# ساختار دلخواه خود را تعریف میکنیم
|
||||
response_data = {
|
||||
'success': False,
|
||||
'status_code': response.status_code,
|
||||
'message': 'An error occurred',
|
||||
'details': {}
|
||||
'status_message': str(getattr(exc, 'default_detail', exc)),
|
||||
'details': getattr(exc, 'detail', None),
|
||||
}
|
||||
|
||||
if isinstance(exc, APIException):
|
||||
response_data['message'] = exc.detail if isinstance(exc.detail, str) else "Validation error"
|
||||
response_data['details'] = exc.detail if isinstance(exc.detail, dict) else {}
|
||||
try:
|
||||
error = getattr(getattr(exc, 'detail', None), 'code', None) or getattr(exc, 'code', None)
|
||||
if not error:
|
||||
error = getattr(exc, 'default_code')
|
||||
except:
|
||||
error = ''
|
||||
|
||||
# if isinstance(exc.detail, str):
|
||||
# message = exc.detail
|
||||
# elif isinstance(exc.detail, dict):
|
||||
# if 'message' in exc.detail or 'string' in exc.detail:
|
||||
# message = exc.detail.get('message') or exc.detail.get('string')
|
||||
# else:
|
||||
# message = error
|
||||
#
|
||||
# else:
|
||||
# message = error
|
||||
#
|
||||
# response_data['message'] = message
|
||||
response_data['details'] = {"message": exc.detail}
|
||||
response_data['details']['error'] = error
|
||||
response_data['details']['timestamp'] = timezone.now().isoformat()
|
||||
|
||||
response.data = response_data
|
||||
|
||||
|
|
@ -29,6 +53,7 @@ def exception_handler(exc, context):
|
|||
# در فایل middleware.py
|
||||
from django.http import JsonResponse
|
||||
|
||||
|
||||
class ErrorMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
|
@ -43,14 +68,33 @@ class ErrorMiddleware:
|
|||
{
|
||||
"success": False,
|
||||
"status_code": 500,
|
||||
"message": "Internal server error",
|
||||
"details": str(exception) # فقط در حالت توسعه! در تولید بهتر است لاگ شود.
|
||||
"status_message": "Internal server error",
|
||||
"details": str(exception) if settings.DEBUG else None,
|
||||
},
|
||||
status=500
|
||||
)
|
||||
|
||||
|
||||
from rest_framework.exceptions import APIException
|
||||
from rest_framework import status
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class UnprocessableEntity(APIException):
|
||||
status_code = 422
|
||||
status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
|
||||
default_detail = 'The request was well-formed but cannot be processed due to semantic errors.'
|
||||
default_code = 'unprocessable_entity'
|
||||
|
||||
|
||||
class ServiceUnavailable(APIException):
|
||||
status_code = status.HTTP_503_SERVICE_UNAVAILABLE
|
||||
default_ = _('SERVICE_UNAVAILABLE')
|
||||
default_code = 'service_unavailable'
|
||||
default_detail = 'Service Unavailable'
|
||||
|
||||
|
||||
class Conflict(APIException):
|
||||
status_code = status.HTTP_409_CONFLICT
|
||||
default_ = _('CONFLICT')
|
||||
default_code = 'conflict'
|
||||
default_detail = 'Conflict'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue