Przyjazna strona błędów zastępująca WSOD

10

To powinno być najłatwiejsze, ale z jakiegoś powodu po prostu nie mogę tego zrobić.

Próbuję uzyskać przyjazną stronę błędu statycznego, która zastąpi nieprzyjemne 500 scenariuszy. Na razie próbuję zreplikować sytuację 500 na mojej lokalnej maszynie (Drupal 7 działający na MAMP), wrzucając niektóre bzdury na górze mojego template.php w moim motywie, co powoduje sytuację 500, ale dla z jakiegoś powodu dyrektywa ErrorDocument w moim .htaccesspliku konfiguracyjnym lub Apache nie ma wpływu.

To, co robię, jest po prostu następujące:

ErrorDocument 500 /500.html

I mam najprostszą jak dotąd statyczną stronę HTML w katalogu głównym mojej witryny o nazwie 500.html.

Mimo to, gdy celowo łamie template.php, otrzymuję przerażający Biały Ekran Śmierci zamiast mojej miłej przyjaznej strony błędu.

Co robię tutaj źle? Zrobiłem to miliard razy w konfiguracjach innych niż Drupal, ale po prostu nie mogę tego ogarnąć.


AKTUALIZACJA : Wygląda na to, że pytania te są obecnie zbyteczne w moim konkretnym przypadku użycia, ponieważ chmura deweloperska Acquia, której używamy do uruchamiania tej aplikacji, nie obsługuje obecnie nawet dostosowywania stron błędów z serii 500. Mamy nadzieję, że wkrótce wdrożą wsparcie.

Tommi Forsström
źródło
Co się stanie, jeśli dodasz drupal_add_http_header('Status', '503 Service Unavailable');do pliku 500.html?
amator barista

Odpowiedzi:

2

500 stron błędów to wyłącznie strony błędów serwera. Gdy serwer przekaże wykonanie PHP, Drupal / PHP jest odpowiedzialny za wyświetlanie własnej strony błędu. Możesz spróbować powiedzieć Drupalowi, aby przekierował użytkownika na niestandardową stronę błędu wraz z nagłówkiem statusu HTTP 500, gdy otrzyma pewne błędy w try...catchbloku.

Należy jednak pamiętać, że niektóre WSOD mogą wystąpić na poziomie systemu i mogą powodować błąd krytyczny, który natychmiast zatrzymuje wykonywanie i prawdopodobnie uniemożliwia catchwykonanie . Jednym z przykładów jest sytuacja, w której baza danych nie jest odpowiednio dostrojona do obsługi zapytań o określonym rozmiarze (na przykład podczas wykonywania operacji przywracania wszystkich operacji) - baza danych może się udławić, dając insta-WSOD.

Powiedziałbym, że najlepszą rzeczą jest sprawdzenie dzienników błędów Apache, MySQL i PHP i próbowanie wyodrębnienia głównej przyczyny WSOD na podstawie indywidualnych przypadków, w przeciwieństwie do prób ukrywania ich za pomocą dość- strona błędu. Podczas gdy błędy, które powodują typowe 500 stron błędów serwera, są czasami nieuniknione, a produkowanie niestandardowych stron błędów serwera jest możliwe, nie jest możliwe, aby występowały WSOD na żywo.

Wygląda na to, że poprawnie skonfigurowano strony błędów serwera. Trzeba tylko rozróżnić, że typowe strony błędów serwera! = WSOD. Strony błędów serwera mogą być uruchamiane z powodu dużego ruchu i wąskich gardeł w zasobach, ale tak naprawdę nie powinieneś mieć problemów z produkcją WSOD, kropka. Zwykle dzieje się tak z powodu złego kodowania, optymalizacji lub konfiguracji. Jeśli nadal widzisz WSOD, upewnij się, że najpierw znajdziesz (i rozwiążesz) pierwotną przyczynę problemu, a nie próbujesz zastosować do niego band-help.

amator barista
źródło
4
Dzięki za odpowiedź. Masz całkowitą rację co do pierwotnej przyczyny / leczenia objawów. Nie ma to jednak znaczenia dla potrzeby ładnych stron z błędami, ponieważ faktem jest, że w trakcie trwania usługi wystąpią błędy i w takich sytuacjach zawsze lepiej jest komunikować sytuację użytkownikom, zamiast pustych stron lub zwykłego czarno-białego strony „błąd serwera”. Przykładem może być wieloryb na Twitterze. To nie eliminuje potrzeby profesjonalnego profilowania błędów, ale w międzyczasie sprawia, że ​​użytkownicy są mniej źli.
Tommi Forsström,
1
Ponadto w tym przypadku nie ma potrzeby rozróżniania warstw, z których pochodzi błąd (o ile znajduje się pod serwerem http), ponieważ potrzebuję tylko mechanizmów typu catch-all dla błędów w warstwie aplikacji, niezależnie od tego, czy jest to awaria bazy danych , ktoś, kto popełnia kod bzdury (i to, że przeszedł nasz test) i każdą inną możliwą, ale nieoczekiwaną sytuację błędu. Ale jak zaktualizowano w pytaniu, jest to dla mnie obecnie nieistotne, ponieważ chmura programistów Acquia nie obsługuje obecnie dostosowywania stron błędów z serii 500.
Tommi Forsström,
„Chmura programistów Acquia nie obsługuje obecnie dostosowywania stron błędów z serii 500”. Aww pieprzy, to dobrze wiedzieć.
amator barista
Chociaż jest to prawie jedyna mucha w maści z potężną Chmurą Dev Acquii, a także mogą ją wdrożyć w najbliższej przyszłości. Nie mogę mówić wystarczająco dobrze dla Dev Cloud. To niesamowita platforma do uruchamiania usług Drupal!
Tommi Forsström
1

Otrzymujesz WSOD, ponieważ wyłączyłeś raportowanie błędów w php.ini. Jest to kwestia bezpieczeństwa - jeśli masz błąd, a haker zobaczy, co to jest, może potencjalnie użyć go do zhakowania witryny.

Jeśli chcesz przechwycić błąd, musisz włączyć wyświetlanie błędów w php.ini (w przykładzie będą widoczne tylko poważne błędy):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

Następnie możesz ustawić dokumenty błędów w pliku htaccess:

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

Alternatywnie możesz podać błędy w pliku settings.php Drupala .

W NGINX:

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

Ponieważ używasz Apache w MAMP, ustaw go na .htaccess. Pamiętaj, że AllowOverridew konfiguracji apache powinno być włączone (zwykle tak jest).

Alexei Rayu
źródło
ustawianie ErrorDocumentdyrektywy dla 500 odpowiedzi w Drupal nie działa w moich testach
cdmo
500 błędów zwykle nie można ustawić w Drupal. Muszą być ustawione przed Drupalem - w .htaccess, jeśli używasz Apache. W NGINX - zobacz zaktualizowany bilet.
Alexei Rayu
O to mi chodziło. Czy udało Ci się uzyskać dyrektywę ErrorDocument dotyczącą 500 błędów ustawionych w htaccess lub vhost skonfigurowanych do pracy dla witryny Drupal? Z mojego doświadczenia te dyrektywy są ignorowane, Drupal przejmuje obsługę błędów.
cdmo
0

Czy włączyłeś raportowanie błędów? (admin / config / development / logowanie -> Ustaw wszystkie komunikaty o wyświetlaniu komunikatów o błędach )

Domyślnie Drupal pokazuje WSOD jako funkcję bezpieczeństwa.

Patrick Kenny
źródło
Zabawne, że jest włączone i nadal otrzymuję WSOD.
Tommi Forsström
W takim przypadku jest to prawdopodobnie problem MAMP, a nie problem Drupala. Spróbuj włączyć raportowanie błędów w php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) Wyświetlanie błędów jest domyślnie wyłączone w MAMP.
Patrick Kenny
1
Mogę wyświetlać błędy php. To nie jest tak naprawdę problem. Chcę mieć możliwość wyświetlenia czegoś przyjaznego, gdy wystąpią błędy, takiego jak Twitter Whale Fail. Nie mogę tego zrobić: niestandardowe strony błędów dla błędów serii 500.
Tommi Forsström
0

Myślę, że odpowiedzią jest „przeczytaj dokumentację”, patrz https://www.drupal.org/node/195435

Zasadniczo możesz tworzyć pliki szablonów o nazwie maintenance-page.tpl.phpi maintenance-page--offline.tpl.phpkodować niektóre ustawienia w settings.php.

EDYTOWAĆ:

Wydaje się, że nie ma znaczenia, jaki poziom error_reportingjest ustawiony ani czy ustawiłeś display_errorsna onlub off. Gdy masz maintenance-page--offline.tpl.phpplik, Drupal wyświetli tę stronę, gdy baza danych zniknie. Nie ma również znaczenia, co ustawiłeś po /admin/config/development/loggingstronie administratora. Jeśli masz tylko błędy składniowe, co było sytuacją PO, to tak naprawdę nie wyzwoli 500, to jest to 200 z błędem PHP wyświetlanym lub ukrytym na podstawie php.ini display_errorzestawu. Nie ma innego sposobu niż dodanie niestandardowej logiki obsługi błędów w niestandardowym kodzie w razie potrzeby.

cdmo
źródło
Nie jestem pewien, dlaczego zostałem tutaj przegłosowany, oto odpowiedź, której szukałem, kiedy ustaliłem nagrodę. Jeden inny nie dla OP, możesz ustawić error_prepend i dołączyć również standardowe powiadomienia o błędach PHP, jeśli chcesz dalej rozwinąć swoją standardową stronę błędu.
cdmo
0

Zastąpienie wszystkich WSOD czymś innym wymagałoby hakowania rdzenia: nie chcesz tego robić. Drupal definiuje własne programy obsługi błędów w bootstrap.inc i error.inc. Jeśli miałbyś zadzierać z tym kodem, musiałbyś upewnić się, że wziąłeś pod uwagę wszystkie rzeczy, które mogą być złe, gdy wykonanie osiągnie ten etap (brak bazy danych, brak silnika motywu, brak motywu, brak konfiguracji itp.).

akrobata
źródło
Czy kiedykolwiek próbowałeś użyć opcji PHP error_append i error_prepend? Chociaż komunikat o błędzie będzie nadal wyświetlany, wydaje się, że można zaoferować znacznie ładniejszy 500 doświadczenia (przyznane, nie wszystkie błędy PHP, które czynią whitescreen technicznie spowodować reakcję 500, podobnie jak wiele błędów składniowych.)
cdmo
Prawdziwe. Tak czy inaczej prowadzi cię do tego samego ogólnego punktu: nie możesz tego zrobić.
akrobata
0

Zrobiłem projekt piaskownicy, aby to zrobić.

Udało mi się to osiągnąć poprzez rozszerzenie HttpExceptionSubscriberBase w /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','');
      }


    }
?>

Musisz dodać usługę w module.services.yml

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
ummdorian
źródło