Ir al contenido

Excepciones HTTP y página de diagnóstico

Una excepción puede interrumpir la lectura del cuerpo, un middleware, la resolución de dependencias o una acción del controlador. Las capas HTTP y el kernel transforman los fallos que pueden manejar en una respuesta para el cliente. El resultado depende del tipo de excepción, del modo debug y del momento en que ocurre.

Esta página se centra en peticiones y respuestas HTTP. La guía general de excepciones, ubicada en la sección independiente Exceptions, explica app.withExceptionHandler(ExceptionHandler), los contratos de failure, el reporte y los demás contextos del framework.

Durante el procesamiento de una petición, Orionis distingue entre respuestas especiales del flujo HTTP y errores que debe delegar al manejador de aplicación:

  1. Una capa puede resolver directamente el caso, como los errores de validación.
  2. Para los demás errores, el sistema de excepciones reporta el fallo y solicita al handler una respuesta HTTP.
  3. El adaptador ASGI/RSGI entrega esa respuesta con su estado, cabeceras y cuerpo.

En WEB, la capa de sesión también puede capturar errores de sus componentes siguientes y delegarlos mientras la sesión sigue disponible. Por ello, la conversión no ocurre exclusivamente en un único except al final del kernel.

Una respuesta de error no siempre es un 500 ni muestra un traceback. Un fallo de autorización puede producir 403; una ruta inexistente, 404; y un schema inválido, 422 o una redirección según su contexto.

El manejador nativo conserva los estados de las excepciones conocidas. Para las excepciones no reconocidas, consulta app.debug:

ModoLo que solicita el clienteRespuesta nativa ante un error no reconocido
Debug desactivadoHTML u otro Accept sin JSONPágina HTML genérica, estado 500.
Debug desactivadoAccept con JSONJSON 500: {"message": "Internal Server Error"}.
Debug activadoHTMLPágina HTML detallada de excepción, estado 500.
Debug activadoAccept con JSONLa misma página HTML detallada, estado 500.

Una ruta API no garantiza JSON para un fallo inesperado con debug activo. La página detallada permite depurar ese fallo también cuando el endpoint normalmente devuelve JSON. Las políticas de protocolo, como MCP, y los handlers personalizados pueden aplicar otra respuesta.

La configuración se declara mediante APP_DEBUG y se consulta desde config/app.py. Para observar el diagnóstico localmente:

APP_DEBUG=bool:true

Reinicia la aplicación para aplicar su configuración de arranque. Si utilizas compilación, consulta las consideraciones de registro y configuración.

El nombre de entorno APP_ENV no sustituye este ajuste: un entorno llamado producción con debug activo sigue exponiendo el diagnóstico.

Para probar el flujo en una aplicación local, guarda este controlador en app/http/controllers/http_error_demo_controller.py:

from orionis.http import JSONResponse, Request, response
from orionis.http.base import BaseController
class HttpErrorDemoController(BaseController):
async def __call__(self, request: Request) -> JSONResponse:
quantity = int(request.queryParams.get("quantity", "invalid"))
return response.json({"quantity": quantity})

Regístralo en el archivo de rutas API configurado, normalmente routes/api.py:

from app.http.controllers.http_error_demo_controller import HttpErrorDemoController
from orionis.support.facades import Route
Route.get("/http-error-demo", HttpErrorDemoController)

Con la aplicación iniciada, abre /http-error-demo?quantity=invalid o utiliza:

Ventana de terminal
curl -i "http://localhost:8000/http-error-demo?quantity=invalid" -H "Accept: text/html"
curl -i "http://localhost:8000/http-error-demo?quantity=invalid" -H "Accept: application/json"

int("invalid") lanza ValueError. El código nativo no lo convierte automáticamente en un error de input 400: con debug activo, ambas peticiones reciben la página detallada 500. Con quantity=3, el endpoint devuelve {"quantity":3}.

Este endpoint demuestra un fallo de programación o una validación omitida. Para una entrada real, declara un schema de petición o trata explícitamente la conversión; conserva este endpoint sólo como demostración local.

Qué contiene la página y cómo interpretarlo

Sección titulada «Qué contiene la página y cómo interpretarlo»

El encabezado identifica la clase, como ValueError, y el mensaje asociado. La clase indica qué operación falló; el texto aporta el detalle concreto, por ejemplo que una cadena no puede convertirse a entero.

Un mensaje no identifica por sí solo la causa de negocio. Contrástalo con la línea señalada y con los argumentos que esperaba esa operación.

La página muestra el método HTTP y el path que se estaba procesando. Ayudan a distinguir endpoints con lógica parecida y a reproducir el fallo en el recorrido correcto.

El diagnóstico recibe el path de la petición, no un volcado completo de la URL con todos sus parámetros, del cuerpo o de las cabeceras.

Exception Details: archivo, línea y código

Sección titulada «Exception Details: archivo, línea y código»

Cada frame puede mostrar su archivo, número de línea y fragmento de código, destacando la línea del fallo. La ventana incluye hasta cinco líneas: dos anteriores, la línea indicada y dos posteriores.

Esto permite ver la operación junto con su contexto inmediato. En el ejemplo anterior, comienza por la conversión a int y comprueba si la entrada se validó antes.

Si el archivo fuente no puede leerse, el diagnóstico conserva los datos disponibles e indica que no hay código para mostrar. Esto puede ocurrir cuando el código no está disponible como un archivo legible en ese entorno.

El enlace al editor utiliza el protocolo vscode://file/.... Su apertura depende de que el equipo tenga un editor y un navegador que admitan ese protocolo y puedan acceder a la ruta mostrada.

El panel lateral enumera archivo, función y línea de los frames, ordenados del más reciente al más antiguo. Seleccionar uno lleva al bloque de código correspondiente.

Empieza por el frame del fallo y recorre las llamadas que lo precedieron. Eso permite identificar si el error se originó en el controlador, un servicio invocado, la conversión de datos o una dependencia del framework. Los enlaces y el contenido siguen disponibles sin JavaScript; la interacción mejora la navegación entre frames.

DatoPara qué sirve
Orionis FrameworkIdentificar la implementación que está ejecutándose.
PythonComparar el comportamiento del intérprete entre entornos.
EnvironmentReconocer el entorno configurado.
Debug ModeConfirmar el estado de la configuración de diagnóstico.
TimezoneContextualizar operaciones que dependen de fechas y horas.
InterfaceSaber si la entrega HTTP utiliza ASGI o RSGI.

Estos datos permiten comparar una reproducción local con otro despliegue. El panel no enumera todas las variables de entorno ni todas las opciones de configuración.

La página incorpora herramientas que utilizan la información del diagnóstico:

AcciónContenido y comportamiento
Copiar reporteCopia tipo y mensaje, método y path, rutas, líneas y fragmentos de código. El botón depende de que el navegador ofrezca Clipboard API.
GoogleBusca por el tipo de excepción Python; no incluye el reporte completo en esa búsqueda.
ChatGPTAbre un enlace con el diagnóstico codificado en la URL.
DocumentaciónAbre la documentación del framework.

La URL de ChatGPT se construye localmente; renderizar la página no envía una consulta al servicio. Abrir ese enlace sí transmite el contenido incluido en la URL. La implementación limita su longitud a 2048 caracteres: puede omitir snippets, compactar campos o descartar frames antiguos, indicando el recorte. Ese límite pertenece al generador de Orionis.

Antes de compartir un reporte, revisa el mensaje y el código que contiene. Aunque el parser no captura variables locales, el mensaje de una excepción o un fragmento fuente puede contener información privada.

El manejador base recorre la jerarquía de la excepción para reconocer estos casos, incluidas sus subclases:

ExcepciónEstadoMensaje público nativo
AuthenticationException401Unauthenticated
AuthorizationException403This action is unauthorized
RouteNotFound404Route not found
MethodNotAllowed405Method not allowed
PayloadTooLargeException413Payload too large
UnsupportedMediaTypeException415Unsupported media type
CSRFTokenMismatchException419CSRF token mismatch

Estos casos conservan su estado y mensaje tanto con debug activo como desactivado. El handler decide entre JSON y HTML mediante request.wantsJson(), que consulta Accept; no por el nombre del archivo de rutas. Si el fallo de autenticación procede del guard de token, añade WWW-Authenticate: Bearer.

El kernel puede resolver antes algunos casos con su propia respuesta, por lo que el mensaje exacto de un 413 depende de la capa que lo maneje. No todas las excepciones recorren el handler global.

Validación, parsing y otros errores del flujo

Sección titulada «Validación, parsing y otros errores del flujo»
SituaciónTratamiento HTTP predeterminado
Schema inválido en APIJSON 422 con mensajes por campo.
Schema inválido en WEB que espera JSON o es AJAXJSON 422.
Schema inválido en navegación WEB habitualRedirección 302 con errores e input flash.
Límite de cuerpo o buffer excedido en el kernel413; puede resolverse antes de llamar al handler global.
Content-Length inválido, duplicado o ambiguo con Transfer-Encoding400 construido antes de leer el cuerpo.
Ruta inexistente con fallback configuradoEjecuta el fallback correspondiente.
Excepción propia sin tratamiento específicoPolítica del handler de aplicación; por defecto, 500 genérico o diagnóstico según debug.

Un JSON mal formado puede lanzar ValueError; XML o MessagePack utilizan sus excepciones de decodificación. No hay una regla universal que convierta cualquier excepción de parsing en 400. Consulta los errores de lectura de Request y el manejo de validación.

Si una condición de dominio necesita una respuesta como 409, su traducción se define en el handler de aplicación. Capturar una excepción localmente y devolver una respuesta también es válido cuando ese componente puede resolver el caso.

Diagnóstico en desarrollo y respuesta pública

Sección titulada «Diagnóstico en desarrollo y respuesta pública»

Para una aplicación expuesta a usuarios, desactiva debug:

APP_DEBUG=bool:false

Con el handler nativo, un error no reconocido devuelve Internal Server Error sin el traceback. La guía general explica cómo conservar el reporte interno y definir mensajes públicos para errores propios.

Las plantillas de error escapan el HTML y las respuestas nativas incluyen Cache-Control: no-cache, no-store, must-revalidate. El escape evita interpretar texto como HTML; no elimina secretos de los mensajes o del código.

El parser utiliza capture_locals=False y no incorpora automáticamente variables locales, cuerpo, cookies o cabeceras de la petición. Aun así, la página muestra rutas de archivos y código fuente, por lo que corresponde a un contexto de diagnóstico controlado.

DefaultResponses.exception() es un renderer y no aplica por sí mismo el filtro de debug. Una llamada directa desde código propio puede mostrar el diagnóstico aunque debug esté desactivado; conserva la decisión de exposición en la política de manejo.

La conversión a una página de error sucede durante el procesamiento de la petición. La entrega del cuerpo, los productores de streaming y las tareas background ocurren después.

Si un productor falla cuando ya se enviaron cabeceras, no se puede sustituir esa respuesta por una página de excepción. El transporte intenta cerrar los recursos y propaga el fallo. Los errores de background tampoco cambian un estado HTTP que ya se entregó.

Consulta respuestas y entrega HTTP, streaming y SSE y la guía general de excepciones para sus respectivos límites.