Buenas,
Estoy tratando de personalizar la página de error 404 tal y como explican en la página oficial de symfony y he creado en el directorio app/Resources/TwigBundle/views/Exception/
de mi proyecto Symfony2 la plantilla de error error404.html.twig
.
Parece que esto no es suficiente y al activarse createNotFoundException()
sigue mostrando la misma página de error predeterminada. ¿En qué puedo estar fallando? Incluso he cambiado la función is_granted()
por {% if app.user and is_granted('...') %}
de la plantilla frontend.html.twig
de la que heredaba la página de error tal y como se sugiere en el enlace anterior y he limpiado la caché pero nada.
Respuestas
Aunque ya supongo que lo sabes, sólo te recuerdo que las páginas de error cambian solamente en el entorno de producción. En desarrollo sigues viendo las mismas páginas de error por defecto.
Al margen de esto, asegúrate de que el nombre de la plantilla y de los directorios es exactamente el siguiente (cualquier error en el nombre o localización de la plantilla hará que no se utilice):
app/Resources/TwigBundle/views/Exception/error404.html.twig
También lo habrás tenido en cuenta, pero asegúrate de que la aplicación está lanzando realmente el error con código 404. y no cualquier otro error del que no seas consciente. Para eso puedes mirar los logs en app/logs/prod.log
.
Cuando se me ocurran más posibles causas o nos des algo más de información sobre el error, te indico más posibles soluciones.
@javiereguiluz
Ya había leído al respecto que debía cambiar al entorno de producción para ver estas páginas de error. Para ello, cambié en el web/app.php
de mi proyecto, el valor de $kernel = new AppKernel('prod', false);
a $kernel = new AppKernel('prod', true);
aunque no se si esto es lo único que tengo que hacer para que esté en el entorno de producción.
Lo que conseguí con ello es que cuando accedo a http://acme.local/app.php/
en vez de a http://acme.local/app_dev.php/
se muestre sólo el texto sin estilos ni imágenes ni nada. Además accedo al lugar donde se produce el error 404 y casualmente sigue mostrándose la misma página de error por defecto con la imagen del fantasma del pac-man diciendo "Exception detected" y el subtítulo "404 Not Found - NotFoundHttpException".
@Jorge_Gante
¿Alguna idea de por qué no aparece correctamente (sin css) mi web en entorno de producción ni las páginas de error? ¿Qué pasos imprescindibles y mínimos debo seguir para "lanzar" mi app al público?
@Jorge_Gante
Respecto a esto que comentas:
Para ello, cambié en el web/app.php de mi proyecto, el valor de $kernel = new AppKernel('prod', false); por $kernel = new AppKernel('prod', true);
Me temo que no sólo no es necesario que hagas eso, sino que hacerlo es un error bastante importante. No deberías cambiar nunca el valor false
del segundo parámetro del controlador frontal de producción. Este parámetro activa el modo debug y eso es algo que nunca deberías activar en producción.
Respecto a por qué no se te ven los estilos en producción, seguramente es porque no has volcado los estilos al directorio público web/
ejecutando el siguiente comando:
$ php app/console assets:install
Si usas Assetic, ejecuta en su lugar lo siguiente:
$ php app/console assetic:dump --env=prod
Por último, respecto al problema original de que no se te muestran las páginas de error personalizadas, sin ver el código no se me ocurre qué puede estar pasando. ¿Has probado a borrar la caché de la aplicación con el comando php app/console cache:clear --env=prod
?
@javiereguiluz
Entonces entiendo que simplemente accediendo a http://acme.local/app.dev
es suficiente para encontrarnos en el entorno de producción. Ahora lo que ocurre es que me sale una página en blanco al provocar que se lance la excepción, por lo que he ido al prod.log
y me sale lo siguiente:
request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No se ha encontrado ningún supuesto para mostrar. Contacte con su profesor. Nº SUP:18/13" at /home/makelele/NetBeansProjects /wars/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller /Controller.php line 149 [] [] request.ERROR: Exception thrown when handling an exception (Twig_Error_Runtime: An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "" as such route does not exist.") in "::frontend.html.twig" at line 33.) [] []
El primero es el error de tipo NotFoundHttpException
y el segundo es el error de Twig al darse cuenta de que le falta un parámetro para renderizar la plantilla.
¿Puede ser un tema de permisos?
@Jorge_Gante
Ya sé donde está el error. Al parecer existe algún problema con las siguientes condiciones en mi frontend.html.twig
:
{% if (path(app.request.attributes.get('_route')) == path('login')) or (path(app.request.attributes.get('_route')) == path('que_eswars')) or (path(app.request.attributes.get('_route')) == path('requisitos_registro')) or (path(app.request.attributes.get('_route')) == path('pfc_wars')) %}
Si elimino estas condiciones se me muestra la página de error, ahora lo que tendré que averiguar es como encontrar unas instrucciones equivalentes para comprobar la ruta actual.
Un saludo
@Jorge_Gante
La condición {% if %}
que muestras parece un poco excesiva. En primer lugar, sería más eficiente definir el código de esta manera:
{% if app.request.attributes.get('_route') in ['login', 'que_eswars', 'requisitos_registro', 'pfc_wars'] %} ... {% endif %}
En segundo lugar, parece una comprobación demasiado compleja como para añadirla en las plantillas. Quizás se podría pasar desde el controlador a la plantilla una variable especial cuando se cumplan determinadas condiciones. Así el código se simplificaría mucho:
{% if variableEspecial|default(false) %} ... {% endif %}
@javiereguiluz
Gracias por el consejo, lo haré así porque es mucho más claro. El problema está concretamente en la siguiente línea, aunque aún no sé el motivo:
path(app.request.attributes.get('_route'))
Escribir este método en el frontend.html.twig
me lanza un error crítico en Twig con el texto de que no existe la ruta "", cuando se lanza el error 404.
@Jorge_Gante
El error se produce porque el valor app.request.attributes.get('_route')
es una cadena vacía y entonces la función path()
no puede generar la URL porque no le estás pasando ninguna ruta.
Puedes probar a mostrar los atributos de la petición con {{ dump(app.request.attributes) }}
o utilizando el excelente bundle de LadyBug.
@javiereguiluz