Página de error amigable para reemplazar WSOD

10

Esto debería ser lo más fácil de hacer, pero por alguna razón simplemente no puedo hacerlo.

Estoy tratando de obtener una página amigable de error estático para reemplazar los desagradables 500 escenarios. Por ahora solo estoy tratando de replicar una situación 500 en mi máquina local (Drupal 7 ejecutándose en MAMP) agregando algunos caracteres basura en la parte superior de mi template.php en mi tema, lo que desencadena una situación 500, pero para alguna razón la directiva ErrorDocument en mi .htaccessarchivo de configuración o Apache no tiene ningún efecto.

Lo que estoy haciendo es simplemente esto:

ErrorDocument 500 /500.html

Y tengo la página html estática más simple en la raíz de mi sitio con el nombre de 500.html.

Aún así, cuando intencionalmente rompo template.php, obtengo la temida White Screen Of Death en lugar de mi amigable página de error amigable.

¿Qué estoy haciendo mal aquí? Lo he hecho mil millones de veces en configuraciones que no son de Drupal, pero no puedo entenderlo.


ACTUALIZACIÓN : Parece que esta pregunta es bastante redundante en mi caso de uso específico en este momento, ya que la nube de desarrollo de Acquia que utilizamos para ejecutar la aplicación en cuestión ni siquiera admite la personalización de páginas de error de la serie 500 en este momento. Esperamos que implementen soporte para eso pronto.

Tommi Forsström
fuente
¿Qué sucede si agrega drupal_add_http_header('Status', '503 Service Unavailable');a su 500.html?
barista aficionado

Respuestas:

2

500 páginas de error son estrictamente páginas de error del servidor. Una vez que el servidor entrega la ejecución a PHP, Drupal / PHP es responsable de servir su propia página de error. Puede intentar decirle a Drupal que redirija al usuario a una página de error personalizada, junto con un encabezado de estado HTTP 500, cuando recibe ciertos errores dentro de un try...catchbloque.

Sin embargo, tenga en cuenta que algunos WSOD pueden ocurrir a nivel del sistema y podrían causar un error fatal que detenga inmediatamente la ejecución y posiblemente impida la catchejecución . Un ejemplo de esto es cuando su base de datos no está ajustada correctamente para manejar consultas de cierto tamaño (como cuando se realizan operaciones de revertir todas las operaciones): la base de datos puede bloquearse, lo que le proporciona un insta-WSOD.

Diría que lo mejor que puede hacer es verificar sus registros de errores de apache, MySQL y PHP, y tratar de aislar la causa raíz de WSOD caso por caso, en lugar de tratar de ocultarlos con página de error Si bien los errores que causan las típicas páginas de error de 500 servidores a veces son inevitables, y tener páginas de error de servidor personalizadas en producción es factible, tener WSODs en vivo no lo es.

Parece que tiene las páginas de error del servidor configuradas correctamente. ¡Solo necesita hacer la distinción de que las páginas de error típicas del servidor! = WSOD. Las páginas de error del servidor pueden activarse debido al alto tráfico y los cuellos de botella de recursos, pero en realidad no debería haber que ocurran WSOD en la producción, punto. Esto suele suceder debido a una codificación, optimización o configuración deficientes. Si aún ve un WSOD, asegúrese de encontrar primero (y resolver) la causa raíz del problema, en lugar de intentar aplicarle una curita.

barista aficionado
fuente
44
Gracias por tu respuesta. Tienes toda la razón sobre la causa raíz / el tratamiento de los síntomas. Sin embargo, esto es irrelevante para la necesidad de páginas de error agradables, ya que es un hecho que durante la vida útil de un servicio, se producirán errores y en esas situaciones siempre es mejor comunicar la situación a los usuarios de manera agradable en lugar de páginas en blanco o negro genérico en blanco páginas de "error del servidor". El Twitter falla ballena como ejemplo. Eso no elimina la necesidad de un perfil de error profesional, pero mientras tanto, hace que los usuarios estén menos enojados.
Tommi Forsström
1
Además, para este caso no hay necesidad de diferenciar entre las capas de las que se origina el error (siempre que esté debajo del servidor http), ya que solo necesito un mecanismo general para los errores en la capa de la aplicación, ya sea el bloqueo de la base de datos , alguien que comete un código basura (y que pasa nuestra cobertura de prueba) y cualquier otra situación de error concebible pero inesperada. Pero como se actualizó en la pregunta, esto es irrelevante para mí en este momento, ya que la nube de desarrollo de Acquia no admite la personalización de páginas de error de la serie 500 en este momento.
Tommi Forsström
"La nube de desarrollo de Acquia no admite la personalización de páginas de error de la serie 500 en este momento". Aww shucks, eso es bueno saberlo.
barista aficionado
Aunque esa es casi la única mosca en el ungüento con la poderosa Dev Cloud de Acquia y también podrían implementar esto en un futuro cercano. No puedo hablar lo suficientemente bien para la nube de desarrollo. ¡Es una plataforma increíble para ejecutar los servicios de Drupal!
Tommi Forsström
1

Está obteniendo WSOD porque desactivó el informe de errores en php.ini. Este es un problema de seguridad: si tiene un error y el pirata informático ve de qué se trata, puede utilizarlo para piratear el sitio.

Sin embargo, si desea interceptar el error, debe habilitar la visualización de los errores en php.ini (el ejemplo solo mostrará errores graves):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

Y luego, puede configurar los documentos de error en el archivo htaccess:

ErrorDocument 401 http://yourwebsite.com/error-401
ErrorDocument 403 http://yourwebsite.com/error-403
ErrorDocument 500 http://yourwebsite.com/error-500

Alternativamente, puede especificar los errores en el archivo settings.php de Drupal .

En NGINX:

error_page 403 = /error.php?code=403;   
error_page 404 = /error.php?code=404;
error_page 500 = /error.php?code=500;

Como está ejecutando Apache en MAMP, configúrelo en .htaccess. Recuerde que AllowOverrideen la configuración de apache debe estar activado (generalmente lo está).

Alexei Rayu
fuente
establecer una ErrorDocumentdirectiva para 500 respuestas en Drupal no funciona en mis pruebas
cdmo
500 errores generalmente no se pueden configurar en Drupal. Deben configurarse antes de Drupal - en .htaccess si se usa Apache. En NGINX: vea el ticket actualizado.
Alexei Rayu
A eso me refería. ¿Ha podido obtener una directiva ErrorDocument para 500 errores establecidos en una configuración htaccess o vhost para que funcione realmente para un sitio de Drupal? Esas directivas se ignoran en mi experiencia, Drupal se hace cargo del manejo de errores.
cdmo
0

¿Has activado el informe de errores? (admin / config / development / logging -> Establecer todos los mensajes para mostrar mensajes de error )

Por defecto, Drupal muestra un WSOD como una característica de seguridad.

Patrick Kenny
fuente
Es curioso que esté activado y sigo teniendo WSOD.
Tommi Forsström
En ese caso, es probable que sea un problema de MAMP, no un problema de Drupal. Intente activar el informe de errores en php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) La visualización de errores está deshabilitada en MAMP de forma predeterminada.
Patrick Kenny
1
Puedo hacer que los errores de php se muestren bien. Ese no es realmente el problema. Quiero poder mostrar algo amigable cuando ocurren errores, como Fail Whale de Twitter. Eso es lo que no puedo hacer realidad: páginas de error personalizadas para errores de la serie 500.
Tommi Forsström
0

Supongo que la respuesta es "leer los documentos", ver https://www.drupal.org/node/195435

Entonces, básicamente, puede crear los archivos de plantilla nombrados maintenance-page.tpl.phpy maintenance-page--offline.tpl.phpcodificar algunas configuraciones settings.php.

EDITAR:

No parece importar qué nivel error_reportingestá ajustado en o si se ha establecido display_errorsa ono off. Cuando tenga un maintenance-page--offline.tpl.phparchivo en su lugar, Drupal mostrará esta página cuando la base de datos desaparezca. Tampoco importa lo que haya configurado /admin/config/development/loggingen el lado del administrador. Si solo tiene errores de sintaxis, que era la situación del OP, que en realidad no desencadenará un 500, es un 200 con un error de PHP que se muestra u oculta según el php.ini display_errorconjunto. No sé de ninguna otra manera que no sea agregar su lógica personalizada de manejo de errores a través de su código personalizado según sea necesario.

cdmo
fuente
No estoy seguro de por qué me votaron aquí, esta es la respuesta que estaba buscando cuando establecí la recompensa. Otro no para el OP, puede configurar error_prepend y agregar también avisos de error estándar de PHP si desea elaborar más su página de error estándar.
cdmo
0

Reemplazar todos los WSOD por algo más requeriría piratear el núcleo: no desea hacer esto. Drupal define sus propios manejadores de errores en bootstrap.inc y errors.inc. Si tuviera que perder el tiempo con ese código, tendría que asegurarse de tener en cuenta todas las cosas que podrían estar mal cuando la ejecución llegara a esta etapa (sin base de datos, sin motor de temas, sin tema, sin configuración, etc.).

acrosman
fuente
¿Alguna vez trató de usar las opciones error_append y error_prepend de PHP? Si bien el mensaje de error todavía mostrar, parece que usted podría ofrecer una experiencia mucho más agradable 500 (concedida, no todos los errores de PHP que hacen que un whitescreen causa técnicamente una respuesta 500, al igual que muchos errores de sintaxis.)
cdmo
Cierto. De cualquier manera te lleva al mismo punto general: no puedes hacer eso.
acrosman
0

Hice un proyecto de sandbox para hacer esto.

Pude lograr esto extendiendo HttpExceptionSubscriberBase en /src/EventSubscriber/fivehundredEventSubscriber.php

    <?php
namespace Drupal\five_hundred\EventSubscriber;

use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Serializer\SerializerInterface;

class five_hundredEventSubscriber extends HttpExceptionSubscriberBase {

      public function __construct($stack) {

        if(
          (
            null !== $stack->getCurrentRequest()->attributes->get('exception')->getCode()
            && $stack->getCurrentRequest()->attributes->get('exception')->getCode() == 500
          )||(
            null !== $stack->getCurrentRequest()->attributes->get('exception')->getStatusCode()
            && $stack->getCurrentRequest()->attributes->get('exception')->getStatusCode() == 500
          )
        ){
            $response = new Response();
            $errorDocumentHtml = 'html here';
            $response->setContent($errorDocumentHtml);
            $response->setStatusCode(500, '500 Internal Server Error');
            $response->send();
            die();
        }
      }

      /**
       * {@inheritdoc}
       */
      protected function getHandledFormats() {
        return array('html','');
      }


    }
?>

Y deberá agregar el servicio en su module.services.yml

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
ummdorian
fuente