Ver índice de contenidos del libro

3.7. Páginas de error bonitas con Django

Tomémonos un momento para admirar la bonita aplicación web que hemos creado hasta ahora ... y ahora ¡rompámosla! Introduzcamos deliberadamente un error de Python en el archivo views.py comentando la línea offset = int(offset) de la vista hours_ahead:

def hours_ahead(request, offset):
    #offset = int(offset)
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
    return HttpResponse(html)

Ejecuta el servidor de desarrollo y navega a /time/plus/3/. Verás una página de error con mucha información significativa, incluyendo el mensaje TypeError mostrado en la parte superior de la página: "unsupported type for timedelta hours component: str".

¿Qué ha ocurrido? Bueno, la función datetime.timedelta espera que el parámetro hours sea un entero, y hemos comentado la línea de código que realiza la conversión del offset a entero. Eso causa que datetime.timedelta lance un TypeError. Es el típico pequeño bug que todo programador comete en algún momento.

El punto de este ejemplo fue demostrar la página de error de Django. Dediquemos un momento a explorar esta página y descubrir las distintas piezas de información que nos brinda.

Aquí comentamos algunas cosas a destacar:

  • En la parte superior de la página se muestra la información clave de la excepción: el tipo y cualquier parámetro de la excepción (el mensaje "unsupported type" en este caso), el archivo en el cuál la excepción fue lanzada, y el número de línea que contiene el error.
  • Abajo de la información clave de la excepción, la página muestra el traceback de Python para dicha excepción. Este es el traceback estándar que se obtiene en el interprete de Python, sólo que más interactivo. Por cada marco de la pila, Django muestra el nombre del archivo, el nombre de la función/método, el número de línea, y el código fuente de esa línea.

    Haz click en la línea de código (en gris oscuro) para ver varias líneas anteriores y posteriores a la línea errónea, lo que nos brinda un poco de contexto.

    Haz click en "Locals vars" debajo de cualquier marco de la pila para ver la tabla de todas las variables locales y sus valores, en ese marco y en la posición exacta de código en el cual fue lanzada la excepción. Esta información de depuración es invaluable.

  • Nota el texto "Switch to copy-and-paste view" debajo de la cabecera "Traceback". Haz click en esas palabras, y el traceback cambiará a una versión que te permitirá fácilmente copiar y pegar. Usando esto para cuando necesitemos compartir el traceback de la excepción con otros para obtener soporte técnico — como los amables colegas que encontraremos en el canal de IRC o la lista de correo de Django.
  • A continuación, la sección "Request information" incluye una gran cantidad de información sobre la petición Web que provocó el error: información GET y POST, valores de las cookies y meta información como las cabeceras CGI. El Apéndice H es una completa referencia sobre toda la información que contienen los objetos peticiones. Más abajo, la sección "Settings" lista la configuración de la instalación de Django en particular. El Apéndice E, cubre en detalle los ajustes de configuración disponibles. Por ahora, sólo mira los ajustes para tener una idea de la información disponible.

La página de error de Django es capaz de mostrar más información en ciertos casos especiales, como por ejemplo, en el caso de error de sintaxis en las plantillas. Lo abordaremos más tarde, cuando discutamos el sistema de plantillas de Django. Por ahora, quita el comentario en la línea offset = int(offset) para que la función de vista funcione normalmente de nuevo.

¿Eres el tipo de programador al que le gusta depurar con la ayuda de sentencias print cuidadosamente colocadas? Puedes usar la página de error de Django para hacer eso — sin la sentencia print. En cualquier punto de la vista, temporalmente podemos insertar un assert False para provocar una página de error. Luego, podremos ver las variables locales y el estado del programa. (Hay maneras más avanzadas de depurar las vista en Django, lo explicaremos más adelante, pero esto es la forma más rápida y fácil).

Finalmente, es obvio que la mayor parte de la información es delicada — expone las entrañas del código fuente de Python, como también de la configuración de Django — y sería una estupidez mostrarla al público en Internet. Una persona con malas intenciones podría usar esto para intentar aplicar ingeniería inversa en la aplicación Web y hacer cosas maliciosas. Por esta razón, la página de error es mostrada sólo cuando el proyecto está en modo depuración. Explicaremos cómo desactivar este modo más adelante. Por ahora, hay que tener en claro que todos los proyectos de Django están en modo depuración automáticamente cuando son creados. (¿Suena familiar? Los errores "Page not found", descritos en la sección "Errores 404", trabajan de manera similar.)