Pagina di errore amichevole per sostituire WSOD


10

Questa dovrebbe essere la cosa più semplice da fare, ma per qualche ragione non riesco proprio a farlo.

Sto cercando di ottenere una pagina di errore statico amichevole per sostituire i cattivi 500 scenari. Per ora sto solo cercando di replicare una situazione di 500 sul mio computer locale (Drupal 7 in esecuzione su MAMP) inserendo alcuni personaggi di merda nella parte superiore del mio template.php nel mio tema, che fa scattare una situazione di 500, ma per per qualche motivo la direttiva ErrorDocument nel mio .htaccessfile di configurazione Apache o non ha alcun effetto.

Quello che sto facendo è semplicemente questo:

ErrorDocument 500 /500.html

E ho la pagina HTML più semplice e statica nella radice del mio sito con il nome di 500.html.

Tuttavia, quando rompo intenzionalmente template.php, ottengo il temuto White Screen Of Death invece della mia simpatica pagina di errore amichevole.

Cosa sto facendo di sbagliato qui? L'ho fatto un miliardo di volte in configurazioni non Drupal ma non riesco proprio a capirlo.


AGGIORNAMENTO : Sembra che questa domanda sia praticamente ridondante nel mio caso d'uso specifico in questo momento in quanto Dev Cloud di Acquia che utilizziamo per eseguire l'applicazione in questione non supporta nemmeno la personalizzazione delle pagine di errore della serie 500 al momento. Spero che implementeranno presto il supporto per questo.


Cosa succede se aggiungi drupal_add_http_header('Status', '503 Service Unavailable');al tuo 500.html?
barista dilettante,

Risposte:


2

500 pagine di errore sono rigorosamente pagine di errore del server. Una volta che il server ha passato l'esecuzione a PHP, Drupal / PHP sono responsabili della pubblicazione della propria pagina di errore. Potresti provare a dire a Drupal di reindirizzare l'utente a una pagina di errore personalizzata, insieme a un'intestazione di stato HTTP 500, quando riceve determinati errori all'interno di un try...catchblocco.

Tuttavia, si noti che alcuni WSOD possono verificarsi a livello di sistema e potrebbero causare un errore irreversibile che interrompe immediatamente l'esecuzione e potrebbe impedire l' catchesecuzione . Un esempio di ciò è quando il database non è correttamente ottimizzato per gestire query di determinate dimensioni (come quando si esegue un'operazione Ripristina tutte le operazioni) - il database potrebbe bloccarsi, dandoti un insta-WSOD.

Direi che la cosa migliore da fare è controllare i log degli errori apache, MySQL e PHP e provare a isolare la causa principale di WSOD caso per caso, invece di cercare di coprirli con un bel- pagina di errore. Mentre gli errori che causano le tipiche 500 pagine di errore del server a volte sono inevitabili e avere pagine di errore del server personalizzate in produzione è fattibile, avere WSOD in diretta non lo è.

Sembra che le pagine di errore del server siano configurate correttamente. Hai solo bisogno di fare la distinzione che tipiche pagine di errore del server! = WSODs. Le pagine di errore del server possono essere attivate a causa del traffico elevato e dei colli di bottiglia delle risorse, ma in realtà non dovresti avere WSOD durante la produzione. Questi in genere si verificano a causa della scarsa codifica, ottimizzazione o configurazione. Se vedi ancora un WSOD, assicurati di trovare (e risolvere) prima la causa principale del problema, invece di provare ad applicare un cerotto ad esso.


4
Grazie per la tua risposta. Hai assolutamente ragione sulla causa principale / sul trattamento dei sintomi. Ciò è tuttavia irrilevante per la necessità di belle pagine di errore poiché è un dato di fatto che durante la durata di un servizio, si verificheranno errori e in quelle situazioni è sempre meglio comunicare la situazione agli utenti piuttosto che con pagine bianche o generici nero su bianco pagine "errore del server". La balena fallita di Twitter come esempio. Ciò non toglie la necessità di profilare errori professionali, ma nel frattempo rende gli utenti meno arrabbiati.
Tommi Forsström,

1
Inoltre, in questo caso non è necessario distinguere tra i livelli da cui proviene l'errore (purché si trovi al di sotto del server http) in quanto ho solo bisogno di un meccanismo catch-all per errori nel livello dell'applicazione, sia che si tratti del crash del database , qualcuno che commette codice di merda (e che passa la copertura del nostro test) e qualsiasi altra situazione di errore immaginabile ma inaspettata. Ma come aggiornato nella domanda, questo è irrilevante per me al momento in quanto il cloud di sviluppo di Acquia non supporta al momento la personalizzazione delle pagine di errore della serie 500.
Tommi Forsström,

"Al momento il cloud di sviluppo di Acquia non supporta la personalizzazione delle pagine di errori della serie 500". Aww shucks, è buono a sapersi.
barista dilettante,

Sebbene sia quasi l'unica mosca dell'unguento con il potente Dev Cloud di Acquia e potrebbero anche implementarlo nel prossimo futuro. Non posso parlare abbastanza bene per Dev Cloud. È una piattaforma straordinaria su cui eseguire i servizi Drupal!
Tommi Forsström,

1

Stai ricevendo WSOD perché hai disattivato la segnalazione degli errori in php.ini. Questo è un problema di sicurezza: se hai un errore e l'hacker vede di cosa si tratta, potrebbe potenzialmente utilizzarlo per hackerare il sito.

Se vuoi intercettare l'errore, però, devi abilitare la visualizzazione degli errori in php.ini (l'esempio mostrerà solo errori gravi):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

E poi, puoi impostare i documenti di errore nel file htaccess:

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

In alternativa, puoi specificare gli errori nel file settings.php di Drupal .

In NGINX:

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

Dato che stai eseguendo Apache in MAMP, impostalo in .htaccess. Ricorda che AllowOverridein apache config dovrebbe essere attivo (di solito lo è).


l'impostazione di una ErrorDocumentdirettiva per 500 risposte in Drupal non funziona nei miei test
cdmo

500 errori di solito non possono essere impostati in Drupal. Devono essere impostati prima di Drupal - in .htaccess se si utilizza Apache. In NGINX - vedi il ticket aggiornato.
Alexei Rayu,

Ecco cosa intendevo. Sei stato in grado di ottenere una direttiva ErrorDocument per 500 errori impostati in un htaccess o un vhost configurato per funzionare effettivamente per un sito Drupal? Quelle direttive sono ignorate nella mia esperienza, Drupal assume la gestione degli errori.
cdmo,

0

Hai attivato la segnalazione errori? (admin / config / development / logging -> Imposta tutti i messaggi per visualizzare i messaggi di errore )

Per impostazione predefinita, Drupal mostra un WSOD come funzionalità di sicurezza.


Abbastanza divertente, questo è acceso e ho ancora WSOD.
Tommi Forsström,

In quel caso è probabilmente un problema MAMP, non un problema Drupal. Prova ad attivare la segnalazione errori in php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) La visualizzazione degli errori è disabilitata in MAMP per impostazione predefinita.
Patrick Kenny,

1
Posso visualizzare bene gli errori PHP. Non è proprio questo il problema. Voglio essere in grado di mostrare qualcosa di amichevole quando si verificano errori, come Fail Whale di Twitter. È la cosa che non posso fare: pagine di errore personalizzate per errori della serie 500.
Tommi Forsström,

0

Immagino che la risposta sia "leggi i documenti", vedi https://www.drupal.org/node/195435

Quindi in pratica puoi creare i file modello denominati maintenance-page.tpl.phpe inserire maintenance-page--offline.tpl.phpalcune impostazioni nel codice settings.php.

MODIFICARE:

Non sembra importare a quale livello error_reportingè impostato o se è stato impostato display_errorssu ono off. Quando si dispone di un maintenance-page--offline.tpl.phpfile, Drupal visualizzerà questa pagina quando il database scompare. Inoltre, non importa ciò che hai impostato /admin/config/development/loggingnel lato amministratore. Se hai solo errori di sintassi, che era la situazione del PO, che in realtà non innescherebbe un 500, è un 200 con un errore PHP visualizzato o nascosto in base al php.ini display_errorset. Non è possibile che io sappia altro che aggiungere la logica di gestione degli errori personalizzata in tutto il codice personalizzato, se necessario.


Non sono sicuro del motivo per cui sono stato votato qui, questa è la risposta che stavo cercando quando ho impostato la taglia. Un altro non per l'OP, è possibile impostare error_prepend e aggiungere anche su avvisi di errore PHP standard se si desidera elaborare ulteriormente la pagina di errore standard.
cdmo,

0

Sostituire tutti i WSOD con qualcos'altro richiederebbe un core di hacking: non vuoi farlo. Drupal definisce i propri gestori di errori in bootstrap.inc e errors.inc. Se dovessi pasticciare con quel codice, dovresti assicurarti di tenere conto di tutte le cose che potrebbero essere sbagliate quando l'esecuzione raggiunge questa fase (nessun database, nessun motore di temi, nessun tema, nessuna configurazione, ecc.).


Hai mai provato a usare le opzioni error_append e error_prepend di PHP? Mentre il messaggio di errore continuerebbe a essere visualizzato, sembra che tu possa offrire un'esperienza molto più piacevole di 500 (garantito, non tutti gli errori PHP che rendono tecnicamente una schermata bianca causano una risposta 500, come molti errori di sintassi.)
cdmo

Vero. In entrambi i casi ti porta allo stesso punto generale: non puoi farlo.
Acrosman,

0

Ho realizzato un progetto sandbox per farlo.

Sono stato in grado di ottenere questo risultato estendendo la HttpExceptionSubscriberBase in /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 dovrai aggiungere il servizio in module.services.yml

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.