Página de erro amigável para substituir o WSOD


10

Essa deve ser a coisa mais fácil de fazer, mas por alguma razão eu simplesmente não consigo fazer isso.

Estou tentando obter uma página de erro estático amigável para substituir os 500 cenários desagradáveis. Por enquanto, estou apenas tentando replicar uma situação 500 na minha máquina local (Drupal 7 em execução no MAMP), inserindo alguns caracteres ruins no topo do meu template.php no meu tema, o que desencadeia uma situação 500, mas para por algum motivo, a diretiva ErrorDocument no meu .htaccessarquivo de configuração ou no Apache não tem efeito.

O que estou fazendo é simplesmente isso:

ErrorDocument 500 /500.html

E eu tenho a página html estática mais simples de sempre na raiz do meu site, com o nome de 500.html.

Ainda assim, quando intencionalmente quebro o template.php, recebo a temida Tela Branca da Morte, em vez da minha agradável página de erro amigável.

O que estou fazendo de errado aqui? Eu já fiz isso um bilhão de vezes em configurações que não são do Drupal, mas simplesmente não consigo entender isso.


ATUALIZAÇÃO : Parece que essas perguntas são bastante redundantes no meu caso de uso específico agora, já que o Dev Cloud da Acquia que usamos para executar o aplicativo em questão nem suporta a personalização de páginas de erro da série 500 no momento. Esperamos que eles implementem suporte para isso em breve.


O que acontece se você adicionar drupal_add_http_header('Status', '503 Service Unavailable');ao seu 500.html?
barista amador

Respostas:


2

500 páginas de erro são estritamente páginas de erro do servidor. Depois que o servidor transfere a execução para o PHP, o Drupal / PHP é responsável por exibir sua própria página de erro. Você pode tentar dizer ao Drupal para redirecionar o usuário para uma página de erro personalizada, juntamente com um cabeçalho de status HTTP 500, quando receber certos erros em um try...catchbloco.

No entanto, observe que alguns WSODs podem ocorrer no nível do sistema e podem causar um erro fatal que interrompe imediatamente a execução e possivelmente impede a catchexecução . Um exemplo disso é quando seu banco de dados não está ajustado adequadamente para lidar com consultas de determinado tamanho (como ao fazer um recurso reverter todas as operações) - o banco de dados pode engasgar, fornecendo um insta-WSOD.

Eu diria que a melhor coisa a fazer é verificar seus logs de erro do apache, MySQL e PHP e tentar isolar a causa raiz do WSOD caso a caso, em vez de tentar encobri-los com um página de erro. Embora os erros que causam as 500 páginas de erro típicas do servidor às vezes sejam inevitáveis ​​e a possibilidade de ter páginas de erro personalizadas do servidor em produção seja viável, não é possível ter WSODs ativos ao vivo.

Parece que você tem as páginas de erro do servidor configuradas corretamente. Você só precisa fazer a distinção de que páginas de erro típicas do servidor! = WSODs. As páginas de erro do servidor podem ser acionadas por causa de alto tráfego e gargalos de recursos, mas você realmente não deve ter WSODs na produção, ponto final. Normalmente, isso ocorre devido à codificação, otimização ou configuração inadequadas. Se você ainda vir um WSOD, encontre (e resolva) a causa raiz do problema primeiro, em vez de tentar aplicar um curativo.


4
Obrigado pela sua resposta. Você está absolutamente certo sobre a causa raiz / tratamento dos sintomas. No entanto, isso é irrelevante para a necessidade de páginas de erro agradáveis, pois é fato que, durante a vida útil de um serviço, ocorrerão erros e, nessas situações, é sempre melhor comunicar a situação aos usuários de maneira agradável do que com páginas em branco ou preto e branco genérico páginas "erro no servidor". O Twitter falha baleia como um exemplo. Isso não elimina a necessidade de criação de perfil de erro profissional, mas, por enquanto, deixa os usuários menos irritados.
Tommi Forsström

1
Além disso, nesse caso, não há necessidade de diferenciar as camadas das quais o erro se origina (desde que esteja abaixo do servidor http), pois eu só preciso de mecanismos abrangentes para erros na camada do aplicativo, seja a queda do banco de dados , alguém que cometeu um código de porcaria (e que passou na nossa cobertura de teste) e qualquer outra situação de erro concebível e inesperada. Mas, conforme atualizado na pergunta, isso é irrelevante para mim no momento, pois a nuvem de desenvolvimento da Acquia não suporta a personalização de páginas de erro da série 500 no momento.
Tommi Forsström

"A nuvem de desenvolvimento da Acquia não suporta a personalização de páginas de erro da série 500 no momento." Aww shucks, isso é bom saber.
barista amador

Embora essa seja quase a única mosca na pomada com a poderosa Dev Cloud de Acquia e eles também podem implementar isso em um futuro próximo. Não posso falar o suficiente para a nuvem de desenvolvimento. É uma plataforma incrível para executar serviços Drupal!
Tommi Forsström

1

Você está recebendo o WSOD porque desativou o relatório de erros no php.ini. Esse é um problema de segurança - se você tiver um erro e o hacker perceber o que é, ele poderá usá-lo para invadir o site.

Se você deseja interceptar o erro, é necessário ativar a exibição dos erros no php.ini (o exemplo mostrará apenas erros graves):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

E então, você pode definir os documentos de erro no arquivo htaccess:

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

Como alternativa, você pode especificar os erros no arquivo settings.php do Drupal .

No NGINX:

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

Como você está executando o Apache no MAMP, configure-o em .htaccess. Lembre-se de que AllowOverrideno apache a configuração deve estar ativada (geralmente é).


definição de uma ErrorDocumentdirectiva por 500 respostas em Drupal não funciona no meu teste
cdmo

500 erros geralmente não podem ser definidos no Drupal. Eles precisam ser configurados antes do Drupal - no .htaccess, se estiver usando o Apache. Em NGINX - veja o ticket atualizado.
Alexei Rayu

Foi isso que eu quis dizer. Você conseguiu obter uma diretiva ErrorDocument para 500 erros configurados em um htaccess ou um vhost configure para realmente funcionar em um site Drupal? Essas diretivas são ignoradas na minha experiência, Drupal assume o controle de erros.
cdmo

0

Você ativou o relatório de erros? (admin / config / development / log - - Definir todas as mensagens para exibir as mensagens de erro )

Por padrão, o Drupal mostra um WSOD como um recurso de segurança.


Engraçado o suficiente, que está ativado e eu ainda recebo o WSOD.
Tommi Forsström

Nesse caso, é provável que seja um problema do MAMP, não um problema do Drupal. Tente ativar o relatório de erros no php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) A exibição de erros está desativada no MAMP por padrão.
Patrick Kenny

1
Eu posso obter erros de php exibidos bem. Esse não é realmente o problema. Quero poder exibir algo amigável quando erros acontecerem, como o Fail Whale do Twitter. Não é possível fazer isso: páginas de erro personalizadas para erros da série 500.
Tommi Forsström

0

Eu acho que a resposta é "leia os documentos", consulte https://www.drupal.org/node/195435

Então, basicamente, você pode criar os arquivos de modelo nomeados maintenance-page.tpl.phpe maintenance-page--offline.tpl.phpcodificar algumas configurações settings.php.

EDITAR:

Não parece importar em que nível error_reportingestá definido ou se você definiu display_errorscomo onou off. Quando você possui um maintenance-page--offline.tpl.phparquivo, o Drupal exibirá esta página quando o banco de dados desaparecer. Também não importa o que você definiu no /admin/config/development/logginglado do administrador. Se você tiver apenas erros de sintaxe, que eram a situação do OP, que na verdade não acionam 500, é um 200 com um erro de PHP exibido ou oculto com base no php.ini display_errorconjunto. Sei que não há outra maneira de adicionar sua lógica personalizada de tratamento de erros em todo o código personalizado, conforme necessário.


Não sei por que recebi voto negativo aqui, esta é a resposta que eu estava procurando quando defini a recompensa. Outro não para o OP, você pode definir error_prepend e anexar também nos avisos de erro padrão do PHP se desejar elaborar mais sua página de erro padrão.
Cdmo

0

Substituir todo o WSOD por outra coisa exigiria um núcleo de hackers: você não deseja fazer isso. O Drupal define seus próprios manipuladores de erro em bootstrap.inc e errors.inc. Se você estivesse mexendo com esse código, teria que se certificar de que era responsável por todas as coisas que poderiam estar erradas quando a execução atingir esse estágio (sem banco de dados, sem mecanismo de tema, sem tema, sem configuração, etc.).


Já tentou usar as opções error_append e error_prepend do PHP? Enquanto a mensagem de erro ainda iria exibir, parece que você poderia oferecer um mais agradável 500 experiência muito (concedido, nem todos os erros do PHP que fazem uma whitescreen tecnicamente causar uma resposta 500, como muitos erros de sintaxe.)
cdmo

Verdade. De qualquer maneira, você chega ao mesmo ponto geral: você não pode fazer isso.
Acrosman

0

Eu fiz um projeto de sandbox para fazer isso.

Consegui fazer isso estendendo o HttpExceptionSubscriberBase em /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','');
      }


    }
?>

E você precisará adicionar o serviço no seu module.services.yml

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.