Обход APIExceptions в django-rest-framework
Я хотел бы понять последствия следующего выбора дизайна для приложения, построенного с использованием DRF.
Нормально ли, если я решу поднимать исключения, которые не являются экземпляром
APIException
в сочетании сcustom_exception_handler
, который может обрабатывать все эти исключения?
Насколько я понимаю, обработчик для конкретного запроса определяется в методе rest_framework.views.APIView.dispatch
(source) и handler
вызывается в блоке try...catch..
в этом методе dispatch
(source). Таким образом, все исключения, возникающие во время выполнения обработчика, перехватываются внутри метода dispatch
и передаются обработчику исключений (стандартному или пользовательскому). Как мы видим здесь метод dispatch ловит не APIException
, а все Exception
.
Так могу ли я просто поднимать свои собственные CustomException(s)
, которые являются подклассами Exception
в моем приложении и просто обрабатывать все эти исключения так, как я хочу в custom_exception_handler
?
Я понимаю, что ValidationError
будет исключением, так как сериализаторы и встроенные валидаторы все поднимают ValidationError
. Если я могу переопределить rest_framework.serializers.Serializer.is_valid
в MyCustomSerializer
, я могу поймать rest_Framework.serializers.ValidationError
и бросить MyOwnCustomValidationError
, который может быть обработан custom_exception_handler
. Что-то вроде этого:
def is_valid(self, raise_exception=False):
try:
super().is_valid(raise_exception=raise_exception)
except serializers.ValidationError as drf_validation_err:
my_custom_exception = MyCustomValidationError(drf_validation_err)
raise my_custom_exception
Какие прогнозируемые проблемы с дизайном или обслуживанием кто-нибудь видит в этом, если таковые имеются? Например, если в будущей версии фреймворка появится новый APIException
и если он не будет обрабатываться моим custom_exception_handler
, то это может стать проблемой. Тем не менее, после обнаружения обработки это должно быть довольно простым делом.
Почему я хочу это сделать?
Я думаю, что это приводит к лучшему дизайну. Я хочу, чтобы мои ответы на ошибки несли больше информации, чем та, что включена в классы исключений drf. Хотя я могу добавить эту дополнительную информацию к каждому исключению в моем custom_exception_handler
, IMHO, гораздо лучше позволить разработчику вызывать соответствующие ошибки/исключения в процессе реализации функциональности. Кроме того, в момент создания исключения доступно больше специфического контекста, чем добавление его на более поздней стадии, когда строится структура ответа.
Почему бы не подклассифицировать сам класс APIException
?
Класс APIException
оборачивает информацию об ошибке (сообщение и код) в объект ErrorDetail
. (поправьте меня, если я ошибаюсь), но если мне нужно, чтобы этот объект нес больше информации, то либо я должен создать свой собственный CustomErrorDetail
и обойти __init()__
метод APIException
(source), чтобы не пытаться завернуть все в ErrorDetail
. TBH, я даже не могу понять, как это вообще может работать.
Мой вопрос не о том, могу ли я это сделать. Я конкретно хочу знать, делаю ли я что-то сейчас, что аукнется мне в будущем. Я смог успешно его реализовать. Но я, вероятно, немного опасаюсь обходить то, что обеспечивает фреймворк.
Если есть лучший способ достичь того, что я хочу, пожалуйста, предложите.
Спасибо за любую информацию.