Page d'erreur conviviale pour remplacer WSOD

10

Cela devrait être la chose la plus simple à faire, mais pour une raison quelconque, je ne peux tout simplement pas le faire.

J'essaie d'obtenir une page d'erreur statique conviviale pour remplacer les 500 scénarios désagréables. Pour l'instant, j'essaie simplement de reproduire une situation 500 sur ma machine locale (Drupal 7 fonctionnant sur MAMP) en ajoutant des caractères de merde en haut de mon template.php dans mon thème, ce qui déclenche une situation 500, mais pour pour une raison quelconque, la directive ErrorDocument dans mon .htaccessfichier de configuration ou Apache n'a aucun effet.

Ce que je fais est tout simplement ceci:

ErrorDocument 500 /500.html

Et j'ai la page html statique la plus simple à la racine de mon site avec le nom de 500.html.

Pourtant, lorsque je casse intentionnellement template.php, j'obtiens le redouté White Screen Of Death au lieu de ma belle page d'erreur conviviale.

Qu'est-ce que je fais mal ici? Je l'ai fait un milliard de fois dans des configurations non Drupal, mais je n'arrive tout simplement pas à comprendre.


MISE À JOUR : Il semble que cette question soit à peu près redondante dans mon cas d'utilisation spécifique en ce moment, car le nuage de développement d'Acquia que nous utilisons pour exécuter l'application en question ne prend même pas en charge la personnalisation des pages d'erreur de la série 500 pour le moment. Nous espérons qu'ils implémenteront bientôt un support pour cela.

Tommi Forsström
la source
Que se passe-t-il si vous ajoutez drupal_add_http_header('Status', '503 Service Unavailable');à votre 500.html?
barista amateur

Réponses:

2

500 pages d'erreur sont strictement des pages d'erreur de serveur. Une fois que le serveur transfère l'exécution à PHP, Drupal / PHP est responsable de servir sa propre page d'erreur. Vous pouvez essayer de dire à Drupal de rediriger l'utilisateur vers une page d'erreur personnalisée, avec un en-tête d'état HTTP 500, lorsqu'il reçoit certaines erreurs dans un try...catchbloc.

Cependant, notez que certains WSOD peuvent se produire au niveau du système et peuvent provoquer une erreur fatale qui arrête immédiatement l'exécution et peut-être empêcher l' catchexécution . Un exemple de cela est lorsque votre base de données n'est pas correctement réglée pour gérer les requêtes d'une certaine taille (comme lors d'une opération de restauration de toutes les fonctionnalités) - la base de données peut s'étouffer, vous donnant un insta-WSOD.

Je dirais que la meilleure chose à faire est de vérifier vos journaux d'erreurs Apache, MySQL et PHP, et d'essayer d'isoler la cause racine de WSOD au cas par cas, au lieu d'essayer de les couvrir avec une jolie- page d'erreur. Bien que les erreurs qui provoquent parfois les 500 pages d'erreur du serveur soient inévitables, et qu'il soit possible d'avoir des pages d'erreur de serveur personnalisées en production, les WSOD ne se produisent pas en direct.

Il semble que les pages d'erreur du serveur soient correctement configurées. Vous avez juste besoin de faire la distinction que les pages d'erreur typiques du serveur! = WSODs. Les pages d'erreur du serveur peuvent être déclenchées en raison du trafic élevé et des goulots d'étranglement des ressources, mais vous ne devriez pas vraiment avoir des WSOD en production, point final. Cela se produit généralement en raison d'un mauvais codage, d'une optimisation ou d'une configuration médiocres. Si vous voyez toujours un WSOD, assurez-vous de trouver (et de résoudre) la cause première du problème, plutôt que d'essayer de lui appliquer un pansement.

barista amateur
la source
4
Merci pour votre réponse. Vous avez absolument raison sur la cause profonde / le traitement des symptômes. Cela n'est cependant pas pertinent pour le besoin de belles pages d'erreur car c'est un fait que pendant la durée de vie d'un service, des erreurs se produiront et dans ces situations, il est toujours préférable de bien communiquer la situation aux utilisateurs plutôt qu'avec des pages vierges ou génériques noir sur blanc pages "erreur serveur". Twitter baleine échoue à titre d'exemple. Cela ne supprime pas la nécessité d'un profilage d'erreur professionnel, mais en attendant, rend les utilisateurs moins en colère.
Tommi Forsström
1
De plus, dans ce cas, il n'est pas nécessaire de faire la différence entre les couches dont l'erreur provient (tant qu'elle se trouve sous le serveur http) car j'ai juste besoin d'un mécanisme de capture pour les erreurs dans la couche application, que ce soit la base de données qui plante , quelqu'un qui commet du code de merde (et qui passe notre couverture de test) et toute autre situation d'erreur imaginable mais inattendue. Mais comme mis à jour dans la question, cela n'est pas pertinent pour moi pour le moment car le cloud de développement d'Acquia ne prend pas en charge la personnalisation des pages d'erreur de la série 500 pour le moment.
Tommi Forsström
"Le cloud de développement d'Acquia ne prend pas en charge la personnalisation des pages d'erreur de la série 500 pour le moment." Aww shucks, c'est bon à savoir.
barista amateur
Bien que ce soit presque la seule mouche dans la pommade avec le puissant nuage de développement d'Acquia, ils pourraient également l'implémenter dans un avenir proche. Je ne peux pas parler assez fort pour le Dev Cloud. C'est une plateforme incroyable pour exécuter les services Drupal!
Tommi Forsström
1

Vous obtenez WSOD parce que vous avez désactivé le rapport d'erreurs dans php.ini. Il s'agit d'un problème de sécurité - si vous avez une erreur et que le pirate voit ce que c'est, il peut potentiellement l'utiliser pour pirater le site.

Si vous voulez intercepter l'erreur, cependant, vous devez activer l'affichage des erreurs dans php.ini (l'exemple ne montrera que les erreurs graves):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

Et puis, vous pouvez définir les documents d'erreur dans le fichier htaccess:

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

Alternativement, vous pouvez spécifier les erreurs dans le fichier settings.php de Drupal .

Dans NGINX:

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

Puisque vous exécutez Apache dans MAMP, définissez-le dans .htaccess. N'oubliez pas que AllowOverridedans apache, la configuration doit être activée (généralement c'est le cas).

Alexei Rayu
la source
définir une ErrorDocumentdirective pour 500 réponses dans Drupal ne fonctionne pas dans mes tests
cdmo
500 Les erreurs ne peuvent généralement pas être définies dans Drupal. Ils doivent être définis avant Drupal - dans .htaccess si vous utilisez Apache. Dans NGINX - voir le ticket mis à jour.
Alexei Rayu
C'est ce que je voulais dire. Avez-vous pu obtenir une directive ErrorDocument pour 500 erreurs définies dans un htaccess ou une configuration vhost pour fonctionner réellement pour un site Drupal? Ces directives sont ignorées dans mon expérience, Drupal prend en charge la gestion des erreurs.
cdmo
0

Avez-vous activé le rapport d'erreurs? (admin / config / development / logging -> Set All messages for Error messages to display )

Par défaut, Drupal affiche un WSOD comme fonctionnalité de sécurité.

Patrick Kenny
la source
Assez drôle, cela est activé et je reçois toujours WSOD.
Tommi Forsström
Dans ce cas, c'est probablement un problème MAMP, pas un problème Drupal. Essayez d' activer le rapport d'erreurs dans php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) L'affichage des erreurs est désactivé par défaut dans MAMP.
Patrick Kenny
1
Je peux afficher correctement les erreurs php. Ce n'est pas vraiment le problème. Je veux pouvoir afficher quelque chose de convivial lorsque des erreurs se produisent, comme Fail Whale de Twitter. C'est la chose que je ne peux pas faire arriver: des pages d'erreur personnalisées pour les erreurs de la série 500.
Tommi Forsström
0

Je suppose que la réponse est "lire les documents", voir https://www.drupal.org/node/195435

Donc, fondamentalement, vous pouvez créer les fichiers de modèle nommés maintenance-page.tpl.phpet maintenance-page--offline.tpl.phpcoder en dur certains paramètres dans settings.php.

ÉDITER:

Il ne semble pas question de quel niveau error_reportingest réglé ou si vous avez défini display_errorsà onou off. Lorsque vous avez un maintenance-page--offline.tpl.phpfichier en place, Drupal affichera cette page lorsque la base de données disparaîtra. Peu importe également ce que vous avez défini /admin/config/development/loggingdans le côté administrateur. Si vous avez juste des erreurs de syntaxe, ce qui était la situation de l'OP, qui ne déclenchera pas réellement un 500, c'est un 200 avec une erreur PHP affichée ou masquée en fonction de l' php.ini display_errorensemble. Il n'y a aucun moyen, à ma connaissance, autre que d'ajouter votre logique de gestion des erreurs personnalisée dans tout votre code personnalisé selon les besoins.

cdmo
la source
Je ne sais pas pourquoi j'ai voté contre ici, c'est la réponse que je cherchais lorsque j'ai fixé la prime. Un autre pas pour l'OP, vous pouvez également définir error_prepend et ajouter des notifications d'erreur PHP standard si vous souhaitez développer davantage votre page d'erreur standard.
cdmo
0

Pour remplacer tous WSOD quelque chose d' autre aurait besoin de piratage de base: vous ne pas vouloir faire cela. Drupal définit ses propres gestionnaires d'erreurs dans bootstrap.inc et errors.inc. Si vous deviez jouer avec ce code, vous devriez vous assurer que vous avez pris en compte toutes les choses qui pourraient mal se passer lorsque l'exécution a atteint ce stade (pas de base de données, pas de moteur de thème, pas de thème, pas de configuration, etc.).

acrosman
la source
Avez-vous déjà essayé d'utiliser les options error_append et error_prepend de PHP? Bien que le message d'erreur s'affiche toujours, il semble que vous pourriez offrir une expérience 500 beaucoup plus agréable (accordé, toutes les erreurs PHP qui font qu'un écran blanc provoquent techniquement une réponse 500, comme de nombreuses erreurs de syntaxe.)
cdmo
Vrai. Dans les deux cas, vous arrivez au même point général: vous ne pouvez pas faire cela.
acrosman du
0

J'ai fait un projet sandbox pour ce faire.

J'ai pu accomplir cela en étendant HttpExceptionSubscriberBase dans /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','');
      }


    }
?>

Et vous devrez ajouter le service dans votre module.services.yml

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