¿Hay alguna manera de manejar todas las excepciones globalmente sin usar el bloque try-except en el marco de descanso de django?
Quiero convertir la página de error html que Django está lanzando a una respuesta de objeto json personalizada.
He creado un archivoException.py en mi aplicación
def custom_exception_handler(exc, context=None): response = exception_handler(exc) if isinstance(exc, HttpResponseServerError): custom_response_data = { 'detail': 'Internal Server Error' # custom exception message } response.data = custom_response_data return responseHe configurado esto en settings.py.
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10, 'EXCEPTION_HANDLER':'my_project.my_app.exceptions.custom_exception_handler'}La respuesta definitiva a su pregunta es no .
Al menos no sé cómo hacerlo globalmente en Django, mientras que global incluye excepciones de middleware).
Además, como lo solicitó @Shubham Kumar, el enlace que necesita es process_exception y para una implementación, consulte esta publicación SO con los documentos oficiales sobre cómo activarlo . Como se indica en los documentos de Django:
request es un objeto HttpRequest. excepción es un objeto de excepción generado por la función de vista.
Django llama a process_exception() cuando una vista genera una excepción. process_exception() debe devolver Ninguno o un objeto HttpResponse. Si devuelve un objeto HttpResponse, se aplicará la respuesta de plantilla y el middleware de respuesta y la respuesta resultante se devolverá al navegador. De lo contrario, se activa el manejo de excepciones predeterminado.
Nuevamente, el middleware se ejecuta en orden inverso durante la fase de respuesta, que incluye process_exception. Si un middleware de excepción devuelve una respuesta, los métodos process_exception de las clases de middleware por encima de ese middleware no se llamarán en absoluto.
Lo que significa que simplemente podrá conectarse a la función de vista y detectar todas esas excepciones.
Dado que me encontré con una situación similar que me llevó a esta pregunta, responderé siguiendo la pregunta original que está relacionada específicamente con Django Rest Framework y no solo con Django.
Entiendo que desea manejar las excepciones generadas desde sus vistas, globalmente, sin tener que definir bloques de prueba/excepto en cada módulo de vista.
DRF le permite definir su propio mecanismo de manejo de excepciones personalizado ( docs ). Aquí hay un ejemplo:
En my_custom_except_handler.py:
import logging from rest_framework.views import exception_handler from django.http import JsonResponse from requests import ConnectionError def custom_exception_handler(exc, context): # Call REST framework's default exception handler first response = exception_handler(exc, context) # checks if the raised exception is of the type you want to handle if isinstance(exc, ConnectionError): # defines custom response data err_data = {'MSG_HEADER': 'some custom error messaging'} # logs detail data from the exception being handled logging.error(f"Original error detail and callstack: {exc}") # returns a JsonResponse return JsonResponse(err_data, safe=False, status=503) # returns response as handled normally by the framework return responseComo se indica en los documentos, el objeto de respuesta definido se refiere a:
La función del controlador de excepciones debe devolver un objeto Respuesta o Ninguno si la excepción no se puede manejar. Si el controlador devuelve Ninguno, la excepción se volverá a generar y Django devolverá una respuesta estándar HTTP 500 de 'error de servidor'.
En otras palabras, la 'respuesta' no será Ninguno solo cuando se manejen estos documentos de excepciones:
Si su controlador personalizado devuelve Ninguno, entonces la excepción será manejada 'normalmente' por el marco, devolviendo el error típico del servidor 500.
Finalmente, recuerde configurar la clave requerida en settings.py:
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'my_project.my_app.my_custom_except_handler.custom_exception_handler'}¡Espero eso ayude!