友好的错误页面来替换WSOD


10

这应该是最简单的事情,但是由于某种原因,我无法完成它。

我正在尝试获取一个友好的静态错误页面,以替换令人讨厌的500种情况。现在,我只是想在本地计算机(运行于MAMP的Drupal 7)上复制500种情况,方法是在主题的template.php顶部添加一些废话字符,这确实会触发500种情况,但是对于由于某种原因,我.htaccess或Apache配置文件中的ErrorDocument指令无效。

我正在做的事情很简单:

ErrorDocument 500 /500.html

我的网站根目录中有一个最简单的静态html页面,名称为500.html。

仍然,当我有意破坏template.php时,我得到的是可怕的死亡白屏,而不是友好的错误页面。

我在这里做错了什么?我已经在非Drupal设置中完成了十亿次操作,但是我无法理解这一点。


更新:在我的特定用例中,这个问题似乎非常多余,因为我们用来运行有问题的应用程序的Acquia的Dev Cloud目前甚至不支持自定义500系列错误页面。希望他们能尽快对此提供支持。


如果添加drupal_add_http_header('Status', '503 Service Unavailable');到500.html,会发生什么?
业余咖啡师,2012年

Answers:


2

500错误页面严格来说是服务器错误页面。一旦服务器将执行移交给PHP,Drupal / PHP将负责提供自己的错误页面。您可以尝试告诉Drupal在一个try...catch块内收到某些错误时,将用户与HTTP 500状态标头一起重定向到自定义错误页面。

但是,请注意,某些WSOD可能会在系统级别发生,并且可能导致致命错误,该错误会立即停止执行并可能阻止catch执行。这方面的一个例子是,如果数据库没有正确调整为处理一定大小的查询(例如执行“功能还原所有操作”时),则数据库可能会阻塞,给您insta-WSOD的麻烦。

我想说的最好的办法是检查您的apache,MySQL和PHP错误日志,并尝试逐案找出WSOD的根本原因,而不是试图用相当大的掩盖它们的方式-错误页面。尽管有时不可避免地会导致典型的500个服务器错误页面的错误,并且在生产环境中使用自定义服务器错误页面是可行的,但实际上无法实时生成WSOD。

看来您已正确设置了服务器错误页面。您只需要区分典型的服务器错误页面!= WSOD即可。服务器错误页面可能是由于高流量和资源瓶颈而触发的,但是您不应该真正在生产期间发生WSOD。这些通常是由于不良的编码,优化或配置而发生的。如果仍然看到WSOD,请确保先找到(并解决)问题的根本原因,而不是尝试对它应用创可贴。


4
感谢您的回答。关于根本原因/治疗症状,您绝对正确。但是,这与良好的错误页面的需求无关,因为这是事实,即在服务的生命周期中会发生错误,在这种情况下,与用户很好地交流情况比总用空白页或普通的黑白更好。 “服务器错误”页面。以Twitter失败的鲸鱼为例。但这并不能消除对专业错误分析的需要,但在此期间,可以减少用户的愤怒。
TommiForsström,2012年

1
另外,在这种情况下,无需区分错误发生的层(只要它位于http服务器下),因为我只需要应用程序层中所有错误的全面机制即可,无论数据库是否崩溃,有人提交废话代码(并且通过了我们的测试覆盖)以及任何其他可能的但出乎意料的错误情况。但是,正如问题中的更新所述,此刻对我而言无关紧要,因为Acquia的开发云目前不支持自定义500系列错误页面。
TommiForsström,2012年

“ Acquia的开发云目前不支持自定义500系列错误页面。” Aww吓坏了,这很高兴知道。
业余咖啡师

尽管这几乎是Acquia强大的Dev Cloud的唯一亮点,而且他们也可能在不久的将来实现这一点。我对Dev Cloud的评价不够高。这是一个运行Drupal服务的绝佳平台!
TommiForsström,2012年

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

另外,您可以在Drupal的settings.php文件中指定错误。

在NGINX中:

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

由于您正在MAMP中运行Apache,因此请在.htaccess中进行设置。请记住,AllowOverride在apache中,config应该是打开的(通常是)。


ErrorDocument在Drupal中设置500个响应的指令在我的测试中
不起作用

通常无法在Drupal中设置500错误。如果使用Apache,则需要在Drupal之前设置它们-.htaccess。在NGINX中-查看更新的票证。
Alexei Rayu '16

我正是这个意思。您是否能够为在htaccess中设置的500个错误或配置为在Drupal站点上实际工作的虚拟主机获取ErrorDocument指令?根据我的经验,这些指令将被忽略,Drupal负责错误处理。
cdmo '16

0

您是否打开了错误报告?(管理/配置/发展/记录- >集的所有邮件进行错误消息的显示

默认情况下,Drupal将WSOD显示为安全功能。


有趣的是,它已打开,我仍然得到WSOD。
TommiForsström2012年

在这种情况下,可能是MAMP问题,而不是Drupal问题。尝试打开php.ini中的错误报告(forum.mamp.info/viewtopic.php?f=2&t=8077)默认情况下,MAMP中的错误显示处于禁用状态。
Patrick Kenny 2012年

1
我可以正常显示php错误。那不是真正的问题。我希望能够在发生错误时显示友好的内容,例如Twitter的“失败的鲸鱼”。那就是我无法实现的事情:500系列错误的自定义错误页面。
TommiForsström2012年

0

我猜答案是“阅读文档”,请参阅https://www.drupal.org/node/195435

因此,基本上,您可以创建名为maintenance-page.tpl.php和的模板文件,maintenance-page--offline.tpl.php并在中对某些设置进行硬编码settings.php

编辑:

它似乎并不无论什么级别error_reporting设置为或你是否已设定display_errorsonoff。当您拥有一个maintenance-page--offline.tpl.php文件时,当数据库消失时,Drupal将显示此页面。您/admin/config/development/logging在管理端设置的内容也没有关系。如果您仅遇到语法错误(这是OP的情况),实际上不会触发500,则是200,并根据php.ini display_error设置显示或隐藏PHP错误。据我所知,除了根据需要在整个自定义代码中添加自定义错误处理逻辑外,没有其他方法。


不知道为什么我在这里被低估了,这是我设置赏金时一直在寻找的答案。另一个不适合OP的用户,如果您想进一步详细说明标准错误页面,也可以设置error_prepend并附加在标准PHP错误通知上。
cdmo '16

0

为了用别的东西代替所有WSOD将需要破解的核心:你希望这样做。Drupal在bootstrap.inc和errors.inc中定义了自己的错误处理程序。如果您要弄乱这些代码,则必须确保考虑到执行到此阶段时所有可能出错的事情(没有数据库,主题引擎,主题,配置等)。


是否曾经尝试使用PHP的error_append和error_prepend选项?尽管错误消息仍会显示,但您似乎可以提供更好的500体验(允许的,并不是所有使白屏产生的PHP错误从技术上讲都会引起500响应,就像许多语法错误一样。)
cdmo

真正。两种方法都可以使您达到相同的普遍观点:您无法做到这一点。
acrosman's

0

我做了一个沙盒项目来做到这一点。

我能够通过扩展/src/EventSubscriber/fivehundredEventSubscriber.php中的HttpExceptionSubscriberBase来实现此目的

    <?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','');
      }


    }
?>

并且您需要在模块中添加服务。services.yml

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.