Дружественная страница ошибки, чтобы заменить WSOD

10

Это должно быть проще всего, но по какой-то причине я просто не могу это сделать.

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

То, что я делаю, довольно просто:

ErrorDocument 500 /500.html

И у меня есть самая простая из когда-либо статичных html-страниц в корне моего сайта с именем 500.html.

Тем не менее, когда я намеренно ломаю template.php, я получаю страшный Белый Экран Смерти вместо моей милой дружественной страницы с ошибкой.

Что я здесь не так делаю? Я делал это миллиард раз в настройках без Drupal, но просто не могу разобраться с этим.


ОБНОВЛЕНИЕ : кажется, что эти вопросы в значительной степени излишни в моем конкретном случае использования прямо сейчас, поскольку Dev Cloud от Acquia, который мы используем для запуска рассматриваемого приложения, даже не поддерживает настройку страниц ошибок серии 500 на данный момент. Мы надеемся, что скоро они осуществят поддержку.

Томми Форсстрём
источник
Что произойдет, если вы добавите drupal_add_http_header('Status', '503 Service Unavailable');в свой 500.html?
любитель бариста

Ответы:

2

500 страниц ошибок - это страницы ошибок сервера. Как только сервер передает выполнение PHP, Drupal / PHP отвечает за обслуживание своей собственной страницы ошибок. Вы можете попробовать сказать Drupal перенаправить пользователя на пользовательскую страницу ошибок вместе с заголовком состояния HTTP 500, когда он получает определенные ошибки в try...catchблоке.

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

Я бы сказал, что лучше всего проверить ваши журналы ошибок apache, MySQL и PHP и попытаться определить причину WSOD в каждом конкретном случае, а не пытаться скрыть их страница ошибки. В то время как ошибки, которые вызывают типичные 500 страниц с ошибками сервера, иногда неизбежны, и наличие пользовательских страниц с ошибками сервера в производстве возможно, наличие WSOD, происходящих вживую, - это не так.

Похоже, вы правильно настроили страницы ошибок сервера. Вам просто нужно различать типичные страницы ошибок сервера! = WSOD. Страницы с ошибками сервера могут быть вызваны из-за большого трафика и узких мест в ресурсах, но на самом деле не должно случиться, чтобы WSOD происходили в производстве. Обычно это происходит из-за плохого кодирования, оптимизации или конфигурации. Если вы все еще видите WSOD, убедитесь, что вы сначала нашли (и решили) основную причину проблемы, а не пытались наложить на нее лейкопластырь.

любитель бариста
источник
4
Спасибо за Ваш ответ. Вы абсолютно правы в отношении основных причин / симптомов лечения. Это, однако, не имеет отношения к потребности в хороших страницах с ошибками, поскольку это факт, что в течение срока службы службы будут возникать ошибки, и в таких ситуациях всегда лучше доводить ситуацию до сведения пользователей лучше, чем с пустыми страницами или обычным черным по белому страницы "ошибка сервера". Щебетать сбойный кит в качестве примера. Это не устраняет необходимость в профессиональном профилировании ошибок, но тем временем делает пользователей менее злыми.
Томми Форсстрем
1
Кроме того, в этом случае нет необходимости различать уровни, из которых возникает ошибка (если она находится ниже http-сервера), поскольку мне просто нужны механизмы универсального контроля ошибок на уровне приложения, будь то сбой базы данных кто-то совершает дерьмовый код (и тот, что проходит наше тестовое покрытие) и любую другую возможную, но неожиданную ситуацию с ошибкой. Но, как уточняется в этом вопросе, в данный момент это не имеет значения для меня, поскольку облако разработки Acquia в настоящее время не поддерживает настройку страниц ошибок серии 500.
Томми Форстрем
«Облако разработчиков Acquia в настоящее время не поддерживает настройку страниц ошибок серии 500». Оуууу, это приятно знать.
любитель бариста
Хотя это почти единственная ложка дегтя с мощным Dev Cloud от Acquia, и они также могут реализовать это в ближайшем будущем. Я не могу говорить достаточно высоко для Dev Cloud. Это удивительная платформа для запуска сервисов Drupal!
Томми Форсстрем
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 конфиг должен быть включен (обычно так и есть).

Алексей Раю
источник
установка 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.
Томми Форстрем
В этом случае это скорее проблема MAMP, а не проблема Drupal. Попробуйте включить сообщение об ошибках в php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ). Отображение ошибок по умолчанию отключено в MAMP.
Патрик Кенни
1
Я могу получить ошибки php отображаются нормально. Это не совсем проблема. Я хочу, чтобы при появлении ошибок отображалось что-то дружелюбное, например Twitter Fail Whale. Это то, чего я не могу добиться: пользовательские страницы ошибок для ошибок 500-й серии.
Томми Форсстрем
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стороне администратора. Если у вас просто есть синтаксические ошибки, которые были в ситуации с OP, то это фактически не вызывает 500, это 200 с ошибкой PHP, отображаемой или скрытой в зависимости от php.ini display_errorнабора. Я знаю, что нет другого способа, кроме как добавлять вашу собственную логику обработки ошибок в ваш собственный код по мере необходимости.

CDMO
источник
Не уверен, почему меня здесь понизили, вот ответ, который я искал, когда назначал награду. Еще одно не для OP, вы можете установить error_prepend и добавить к стандартным уведомлениям об ошибках PHP тоже, если вы хотите более подробно проработать стандартную страницу ошибок.
cdmo
0

Чтобы заменить все WSOD чем-то другим, потребуется взлом ядра: вы не хотите этого делать. Drupal определяет свои собственные обработчики ошибок в bootstrap.inc и errors.inc. Если бы вы возились с этим кодом, вам нужно было бы убедиться, что вы учли все вещи, которые могли быть неправильными, когда выполнение достигло этой стадии (без базы данных, без механизма тем, без темы, без конфигурации и т. Д.).

acrosman
источник
Вы когда-нибудь пытались использовать опции PHP error_append и error_prepend? Хотя сообщение об ошибке все равно будет отображаться, кажется, что вы могли бы предложить гораздо более приятный опыт 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 }
ummdorian
источник