Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Problemas al personalizar la página de error 404 con Symfony

22 de mayo de 2014

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

#1

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

22 mayo 2014, 23:21
#2

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

23 mayo 2014, 11:26
#3

¿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

26 mayo 2014, 17:40
#4

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

26 mayo 2014, 18:00
#5

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

26 mayo 2014, 18:36
#6

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

26 mayo 2014, 19:45
#7

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

26 mayo 2014, 19:59
#8

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

26 mayo 2014, 20:56
#9

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

26 mayo 2014, 21:57