Páginas de error 404 y 500 personalizadas en Flask
Cómo reemplazar las feas páginas de error por defecto de Flask por unas propias, con tu diseño. Manejo de 404, 500 y cómo registrar los errores para enterarte cuando algo falla.
Cuando un usuario entra a una URL que no existe en tu app Flask, ve una página en blanco que dice “Not Found” en texto plano. Igual de fea es la de “Internal Server Error” cuando algo se rompe. En una app real eso desmerece, y además deja al usuario sin salida. Aquí cómo poner tus propias páginas de error, con tu diseño y un enlace de vuelta.
Manejar el 404 (página no encontrada)
Flask usa decoradores errorhandler para interceptar cada tipo de error. Para el 404:
from flask import Flask, render_template
app = Flask(__name__)
@app.errorhandler(404)
def no_encontrada(error):
return render_template("404.html"), 404
El detalle que mucha gente olvida: fíjate en el , 404 al final del return. Eso devuelve el código de estado correcto junto con la página. Si lo omites, la página se muestra pero con código 200 (OK), lo cual confunde a Google y a cualquier sistema que consuma tu sitio. La página de error debe decir “404” también en el código, no solo en el texto.
La plantilla 404.html es HTML normal, con tu diseño:
<h1>Página no encontrada</h1>
<p>La página que buscas no existe o fue movida.</p>
<a href="/">← Volver al inicio</a>
Lo importante: siempre incluye un enlace de vuelta. Una página de error sin salida deja al usuario atrapado.
Manejar el 500 (error interno del servidor)
El 500 aparece cuando tu código lanza una excepción no controlada. Se maneja igual:
@app.errorhandler(500)
def error_servidor(error):
return render_template("500.html"), 500
Pero aquí hay un matiz importante que conviene entender: cuando tienes el modo debug activo (debug=True), Flask no usa tu página 500 — muestra su pantalla de depuración con el detalle del error, que es lo que quieres mientras desarrollas. Tu página 500 personalizada solo aparece en producción, con el debug apagado. Así que para probarla, desactiva el debug.
Enterarte cuando algo falla (lo que de verdad importa)
Una página 500 bonita está bien para el usuario, pero a ti te interesa saber qué se rompió. Si solo muestras la página amable y no registras el error, te quedas ciego: sabes que algo falló, pero no qué. Registra el error antes de responder:
import logging
@app.errorhandler(500)
def error_servidor(error):
app.logger.error(f"Error interno: {error}", exc_info=True)
return render_template("500.html"), 500
El exc_info=True incluye el rastreo completo del error en el log, que es lo que necesitas para diagnosticar. El usuario ve una página amable; tú ves en los logs exactamente qué línea reventó. Esa separación —mensaje amable afuera, detalle técnico en el log— es la marca de una app pensada para producción.
Un manejador para varios errores
Si quieres la misma página para varios códigos (403, 404, 410…), puedes registrar el mismo manejador para todos:
from werkzeug.exceptions import HTTPException
@app.errorhandler(HTTPException)
def manejar_http(error):
return render_template("error.html", codigo=error.code,
nombre=error.name), error.code
Esto atrapa cualquier error HTTP y pasa su código y nombre a una plantilla genérica, que puedes personalizar mostrando el número y una descripción. Menos plantillas que mantener.
Resumen
- Usa
@app.errorhandler(codigo)para cada tipo de error. - Siempre devuelve el código de estado en el
return(, 404), no solo la página. - Incluye un enlace de vuelta en cada página de error.
- La página 500 personalizada solo se ve con
debug=False. - Registra los errores 500 con
exc_info=Truepara poder diagnosticarlos.
Con esto tu app deja de mostrar pantallas crudas y da una experiencia cuidada incluso cuando algo sale mal — que en producción, tarde o temprano, pasa.
¿Quieres que los errores te lleguen por correo automáticamente, o montar una página de error con tu diseño completo? Escríbeme desde contacto y lo vemos.