Дружня сторінка помилок для заміни WSOD


10

Це має бути найпростішою справою, але я чомусь просто не можу це зробити.

Я намагаюся отримати дружню сторінку статичної помилки, щоб замінити 500 неприємних сценаріїв. Наразі я просто намагаюся повторити 500 ситуацій на моїй локальній машині (Drupal 7, що працює на MAMP), вкинувши в мою тему деякі символи лайно, що вгорі, що викликає ситуацію 500, але для чомусь директива ErrorDocument в моєму .htaccessфайлі або конфігурації Apache не впливає.

Що я роблю, це досить просто:

ErrorDocument 500 /500.html

І у мене найпростіша статична html-сторінка в корені мого сайту з назвою 500.html.

І все-таки, коли я навмисно ламаю template.php, я отримую жахливий білий екран смерті замість моєї приємної дружньої сторінки помилок.

Що я тут роблю неправильно? Я це робив мільярд разів у не-друпальських установках, але просто не можу обернутись головою.


ОНОВЛЕННЯ : Мабуть, ці питання в моєму конкретному випадку використання зараз надто вигідні, оскільки облако Dev Cloud, яке ми використовуємо для запуску програми, не підтримує навіть налаштування сторінок помилок на 500 серій. Ось сподіваємось, що незабаром вони реалізують підтримку.


Що станеться, якщо ви додасте drupal_add_http_header('Status', '503 Service Unavailable');до свого 500.html?
любительська бариста

Відповіді:


2

500 сторінок помилок - це суворо сторінки помилок сервера. Після того, як сервер передає виконання PHP, Drupal / PHP несуть відповідальність за обслуговування власної сторінки помилок. Ви можете спробувати сказати Drupal, щоб він перенаправляв користувача на користувацьку сторінку помилок разом із заголовком статусу HTTP 500, коли він отримує певні помилки в try...catchблоці.

Однак зауважте, що деякі WSOD можуть виникати на системному рівні, і вони можуть спричинити фатальну помилку, яка негайно зупиняє виконання та, можливо, заважає catchвиконувати . Одним із прикладів цього є те, коли ваша база даних не налаштована належним чином для обробки запитів певного розміру (як, наприклад, при виконанні функцій, відновлення всіх операцій) - база даних може задихатися, надаючи встановлення WSOD.

Я б сказав, що найкраще зробити це перевірити ваші журнали помилок apache, MySQL та PHP та спробувати виділити першопричину WSOD у кожному конкретному випадку, на відміну від спроб приховати їх досить-таки сторінка помилки. Хоча помилки, що викликають типові сторінки помилок на сервері 500, іноді неминучі, а використання власних сторінок помилок сервера у виробництві можливо, але WSOD-файли трапляються в реальному часі - це не так.

Схоже, у вас неправильно налаштовані сторінки з помилками сервера. Вам просто потрібно зробити відмінність типових сторінок помилок сервера! = WSOD. Сторінки помилок сервера можуть бути запущені через великий трафік та вузькі місця, але ви не повинні насправді мати WSOD у виробництві, періоді. Зазвичай вони трапляються через неякісне кодування, оптимізацію чи конфігурацію. Якщо ви все ще бачите WSOD, переконайтеся, що ви знайдете (і вирішите) першопричину проблеми спочатку, на відміну від спроб застосувати до неї смугову допомогу.


4
Дякую за вашу відповідь. Ви абсолютно праві щодо першопричини / лікування симптомів. Це, однак, не має значення для приємних сторінок помилок, оскільки це факт, що протягом життя служби трапляться помилки, і в таких ситуаціях завжди краще повідомляти ситуацію користувачам красивіше, ніж із порожніми сторінками або загальним чорним на білому сторінки "помилка сервера". Твіттер провалив кита як приклад. Це не знімає потреби в професійному профілюванні помилок, але тимчасово змушує користувачів менше гніватися.
Tommi Forsström

1
Крім того, для цього випадку немає необхідності розмежовувати шари, з яких виникає помилка (доки вона знаходиться під http-сервером), оскільки мені просто потрібні механізми викриття помилок на рівні програми, будь то база даних , хтось вчинив лайновий код (і це проходить тестове покриття) та будь-яку іншу можливу, але несподівану помилку. Але як оновлено у запитанні, це наразі для мене не має значення, оскільки хмара розробників Acquia на даний момент не підтримує налаштування сторінок помилок у 500 серій.
Tommi Forsström

"Хмара розробників Acquia на даний момент не підтримує налаштування сторінок помилок у 500 серій." Aww shucks, це добре знати.
любительська бариста

Хоча це чи не єдина муха в мазі з могутнім Dev Cloud у Acquia, і вони також можуть це здійснити найближчим часом. Я не можу говорити досить високо для хмари Dev. Це дивовижна платформа для запуску служб Drupal!
Tommi Forsström

1

Ви отримуєте WSOD, оскільки ви відключили повідомлення про помилки в php.ini. Це проблема безпеки - якщо у вас є помилка, і хакер бачить, що це таке, він потенційно може використовувати її для злому сайту.

Якщо ви хочете перехопити помилку, вам потрібно увімкнути показ помилок у php.ini (приклад показує лише серйозні помилки):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

А потім ви можете встановити документи про помилку у файлі htaccess:

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

Крім того, ви можете вказати помилки у файлі settings.php Drupal .

У NGINX:

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

Оскільки ви запускаєте Apache в MAMP, встановіть його у .htaccess. Пам’ятайте, що AllowOverrideв apache config повинен бути увімкнено (зазвичай він є).


встановлення ErrorDocumentдирективи щодо 500 відповідей в Drupal не працює в моєму тестуванні
cdmo

500 помилок зазвичай не можна встановити в Drupal. Їх потрібно встановити перед Drupal - в .htaccess, якщо використовується Apache. У NGINX - дивіться оновлений квиток.
Олексій Раю

Це я мав на увазі. Чи вдалося вам отримати ErrorDocument директиву для 500 помилок, встановлених в htaccess або vhost-конфігурації, щоб фактично працювати на сайті Drupal? Ці директиви в моєму досвіді ігноруються, Drupal переймає обробку помилок.
cdmo

0

Ви ввімкнули повідомлення про помилки? (admin / config / development / logging -> Встановити відображення всіх повідомлень для повідомлень про помилки )

За замовчуванням Drupal показує WSOD як функцію захисту.


Досить смішно, що увімкнено, і я все одно отримую WSOD.
Tommi Forsström

У цьому випадку це, швидше за все, проблема MAMP, а не проблема Drupal. Спробуйте ввімкнути повідомлення про помилки в php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) Відображення помилок у MAMP за замовчуванням відключено.
Патрік Кенні

1
Я можу отримати помилки php відображаються добре. Це насправді не проблема. Я хочу мати можливість відобразити щось дружнє, коли трапляються помилки, як, наприклад, Fail Whale Twitter. Це те, чого я не можу зробити: власні сторінки помилок для помилок у 500 серій.
Tommi Forsström

0

Я думаю, що відповідь - "прочитайте документи", див. Https://www.drupal.org/node/195435

Тому в основному ви можете створювати файли шаблону з ім'ям maintenance-page.tpl.phpі maintenance-page--offline.tpl.phpі жорсткий код деякі настройки settings.php.

Редагувати:

Це , здається, не має значення , який рівень error_reportingвстановлений або ви встановили чи display_errorsв onабо off. Коли у вас є maintenance-page--offline.tpl.phpфайл, Drupal відображатиме цю сторінку, коли база даних проходить. Також не має значення, що ви встановили на /admin/config/development/loggingстороні адміністратора. Якщо у вас просто є синтаксичні помилки, що було в ситуації з ОП, це фактично не спричинить 500, це 200 з помилкою PHP, відображеною або прихованою на основі php.ini display_errorнабору. Я не знаю іншого способу, крім того, як додавати вашу власну логіку обробки помилок у вашому користувальницькому коді за потребою.


Не впевнений, чому мене тут заперечують, це відповідь, яку я шукав, коли встановлював щедроту. Окрім інших, не для ОП, ви можете встановити помилку_доповнення та додати до стандартних повідомлень про помилки PHP також, якщо ви хочете далі розробити свою стандартну сторінку помилок.
cdmo

0

Для заміни всіх WSOD на щось інше знадобиться злому ядра: ви цього не хочете робити. Drupal визначає власні оброблячі помилок у bootstrap.inc та errors.inc. Якщо ви зіпсуєтеся з цим кодом, вам доведеться переконатися, що ви врахували всі речі, які можуть бути помилковими, коли виконання досягло цього етапу (жодної бази даних, жодного двигуна теми, жодної теми, без конфігурації тощо).


Ви коли-небудь намагалися використовувати параметри помилок PHP і помилки_подання? Хоча повідомлення про помилку все-таки відображатиметься, схоже, ви могли б запропонувати набагато приємніший досвід 500 (надано, не всі помилки PHP, які роблять пробіл технічно причиною 500 відповідей, як і багато синтаксичних помилок.)
cdmo

Правда. У будь-якому випадку ви досягнете однакової загальної точки: ви не можете цього зробити.
акросман

0

Я зробив проект з пісочниці, щоб це зробити.

Я зміг досягти цього шляхом розширення HttpExceptionSubscriberBase в /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','');
      }


    }
?>

І вам потрібно буде додати послугу у своєму module.services.yml

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.