Обход 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, я даже не могу понять, как это вообще может работать.

Мой вопрос не о том, могу ли я это сделать. Я конкретно хочу знать, делаю ли я что-то сейчас, что аукнется мне в будущем. Я смог успешно его реализовать. Но я, вероятно, немного опасаюсь обходить то, что обеспечивает фреймворк.

Если есть лучший способ достичь того, что я хочу, пожалуйста, предложите.

Спасибо за любую информацию.

Вернуться на верх