Добавление custom_exception_handler
This commit is contained in:
@@ -5,7 +5,8 @@
|
|||||||
# Все права защищены. Лицензия: MIT
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Классов авторизации
|
Пакет классов расширения Django REST Framework
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from .custom_exception_handler import custom_exception_handler
|
||||||
from .expiring_token_authentication import ExpiringTokenAuthentication
|
from .expiring_token_authentication import ExpiringTokenAuthentication
|
||||||
87
net/xeaf/rack/utils/drf/custom_exception_handler.py
Normal file
87
net/xeaf/rack/utils/drf/custom_exception_handler.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# DRF Rack
|
||||||
|
# Библиотека классов расширений для Django REST Framework
|
||||||
|
#
|
||||||
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
||||||
|
# Все права защищены. Лицензия: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Описание функции custom_exception_handler
|
||||||
|
"""
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.exceptions import MethodNotAllowed
|
||||||
|
from rest_framework.exceptions import NotAuthenticated
|
||||||
|
from rest_framework.exceptions import PermissionDenied
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
|
from rest_framework.request import Request
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from net.xeaf.rack.core import CoreException
|
||||||
|
from net.xeaf.rack.models.responses import ErrorResponse
|
||||||
|
from net.xeaf.rack.utils.exceptions import ForbiddenException
|
||||||
|
from net.xeaf.rack.utils.exceptions import NotFoundException
|
||||||
|
from net.xeaf.rack.utils.exceptions import UnauthorizedException
|
||||||
|
|
||||||
|
|
||||||
|
def custom_exception_handler(exc: CoreException | Exception, context: dict) -> Response:
|
||||||
|
"""
|
||||||
|
Универсальный обработчик исключений
|
||||||
|
|
||||||
|
:param exc: Исключение
|
||||||
|
:param context: Контекст
|
||||||
|
|
||||||
|
:return: Ответ
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Получаем информацию о запросе
|
||||||
|
request = context.get("request")
|
||||||
|
assert isinstance(request, Request)
|
||||||
|
|
||||||
|
# Это наше исключение
|
||||||
|
if isinstance(exc, CoreException):
|
||||||
|
return ErrorResponse(status_code=exc.status_code, detail=exc.detail, meta=exc.meta)
|
||||||
|
|
||||||
|
# Проверка на стандартное исключение валидации
|
||||||
|
if isinstance(exc, ValidationError):
|
||||||
|
return _process_validation_exception(exc)
|
||||||
|
|
||||||
|
# Проверка на стандартное исключение авторизации
|
||||||
|
if isinstance(exc, NotAuthenticated):
|
||||||
|
return ErrorResponse(status_code=status.HTTP_401_UNAUTHORIZED, detail=UnauthorizedException.Msg.DEFAULT_MESSAGE)
|
||||||
|
|
||||||
|
# Проверка на стандартное исключение прав доступа
|
||||||
|
if isinstance(exc, PermissionDenied):
|
||||||
|
return ErrorResponse(status_code=status.HTTP_403_FORBIDDEN, detail=ForbiddenException.Msg.DEFAULT_MESSAGE)
|
||||||
|
|
||||||
|
# Проверка на стандартное исключение отсутствия реализации
|
||||||
|
if isinstance(exc, MethodNotAllowed):
|
||||||
|
return ErrorResponse(status_code=status.HTTP_404_NOT_FOUND, detail=NotFoundException.Msg.DEFAULT_MESSAGE)
|
||||||
|
|
||||||
|
# Если ничего другое не прошло
|
||||||
|
return ErrorResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc))
|
||||||
|
|
||||||
|
|
||||||
|
def _process_validation_exception(exc: ValidationError) -> ErrorResponse:
|
||||||
|
"""
|
||||||
|
Обрабатывает частный случай стандартного исключения валидации
|
||||||
|
|
||||||
|
:param exc: Исключение
|
||||||
|
|
||||||
|
:return: Ответ
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(exc.detail, list):
|
||||||
|
if len(exc.detail) == 1:
|
||||||
|
detail = str(exc.detail[0])
|
||||||
|
else:
|
||||||
|
detail = exc.detail
|
||||||
|
elif isinstance(exc.detail, dict):
|
||||||
|
detail = {}
|
||||||
|
for field, error_info in exc.detail.items():
|
||||||
|
if isinstance(error_info, list):
|
||||||
|
error = error_info[0]
|
||||||
|
detail[field] = str(error)
|
||||||
|
else:
|
||||||
|
detail = str(exc.detail)
|
||||||
|
|
||||||
|
return ErrorResponse(status_code=status.HTTP_400_BAD_REQUEST, detail=detail)
|
||||||
@@ -37,10 +37,10 @@ REST_FRAMEWORK = {
|
|||||||
'djangorestframework_camel_case.parser.CamelCaseJSONParser',
|
'djangorestframework_camel_case.parser.CamelCaseJSONParser',
|
||||||
),
|
),
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
'net.xeaf.rack.utils.auth.ExpiringTokenAuthentication',
|
'net.xeaf.rack.utils.drf.ExpiringTokenAuthentication',
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
],
|
],
|
||||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||||
'PAGE_SIZE': 10,
|
'PAGE_SIZE': 10,
|
||||||
# 'EXCEPTION_HANDLER': 'tantal.bdrive.api.utils.custom_exception_handler'
|
'EXCEPTION_HANDLER': 'net.xeaf.rack.utils.drf.custom_exception_handler'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
|
|
||||||
from net.xeaf.rack.core import CoreModel
|
from net.xeaf.rack.core import CoreModel
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
SettingUtils.initialize(
|
SettingUtils.initialize(
|
||||||
base_dir=BASE_DIR,
|
base_dir=BASE_DIR,
|
||||||
env_prefix="RACK_",
|
env_prefix="RACK_",
|
||||||
app_name="DRF Rack Demo",
|
app_name="DRF Rack",
|
||||||
url_root="wsgiapp.urls",
|
url_root="wsgiapp.urls",
|
||||||
wsgi_application="wsgiapp.wsgi.application",
|
wsgi_application="wsgiapp.wsgi.application",
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user