Trang lỗi thân thiện để thay thế WSOD


10

Đây có thể là điều dễ nhất để làm, nhưng vì một số lý do tôi không thể hoàn thành nó.

Tôi đang cố gắng để có được một trang lỗi tĩnh thân thiện để thay thế 500 tình huống khó chịu. Hiện tại tôi chỉ đang cố gắng tái tạo một tình huống 500 trên máy cục bộ của mình (Drupal 7 đang chạy trên MAMP) bằng cách ném một số ký tự tào lao lên trên mẫu.php của tôi trong chủ đề của tôi, điều này gây ra một tình huống 500, nhưng đối với một số lý do chỉ thị ErrorDocument trong .htaccesstệp cấu hình của tôi hoặc Apache không có hiệu lực.

Những gì tôi đang làm khá đơn giản là thế này:

ErrorDocument 500 /500.html

Và tôi có trang html tĩnh đơn giản nhất từng có trong thư mục gốc của trang web của tôi với tên 500.html.

Tuy nhiên, khi tôi cố tình phá vỡ template.php, tôi nhận được White Screen Of Death đáng sợ thay vì trang lỗi thân thiện tốt đẹp của tôi.

Tôi làm gì sai ở đây? Tôi đã thực hiện điều này hàng tỷ lần trong các thiết lập không phải của Drupal nhưng tôi không thể hiểu được điều này.


CẬP NHẬT : Có vẻ như câu hỏi này khá dư thừa trong trường hợp sử dụng cụ thể của tôi ngay bây giờ vì Dev Cloud của Acquia mà chúng tôi sử dụng để chạy ứng dụng trong câu hỏi thậm chí không hỗ trợ tùy chỉnh các trang lỗi 500-series vào lúc này. Đây là hy vọng họ sẽ thực hiện hỗ trợ cho điều đó sớm.


Điều gì xảy ra nếu bạn thêm drupal_add_http_header('Status', '503 Service Unavailable');vào 500.html của mình?
barista nghiệp dư

Câu trả lời:


2

500 trang lỗi là các trang lỗi máy chủ nghiêm ngặt. Khi máy chủ chuyển giao thực thi cho PHP, Drupal / PHP chịu trách nhiệm phục vụ trang lỗi của riêng họ. Bạn có thể thử yêu cầu Drupal chuyển hướng người dùng đến trang lỗi tùy chỉnh, cùng với tiêu đề trạng thái HTTP 500, khi nó nhận được một số lỗi nhất định trong một try...catchkhối.

Tuy nhiên, lưu ý rằng một số WSOD có thể xảy ra ở cấp hệ thống và chúng có thể gây ra lỗi nghiêm trọng ngay lập tức tạm dừng thực thi và có thể ngăn không catchcho thực thi . Một ví dụ về điều này là khi cơ sở dữ liệu của bạn không được điều chỉnh chính xác để xử lý các truy vấn có kích thước nhất định (như khi thực hiện Tính năng hoàn nguyên tất cả hoạt động) - cơ sở dữ liệu có thể bị nghẹt, cung cấp cho bạn một WSOD.

Tôi muốn nói điều tốt nhất cần làm là kiểm tra nhật ký lỗi của bạn, nhật ký lỗi MySQL và PHP và cố gắng tách biệt nguyên nhân gốc của WSOD trên cơ sở từng trường hợp, trái ngược với việc cố gắng che đậy chúng một cách dễ dàng trang lỗi. Mặc dù các lỗi gây ra 500 trang lỗi máy chủ điển hình đôi khi không thể tránh khỏi và việc có các trang lỗi máy chủ tùy chỉnh trong sản xuất là khả thi, nhưng có WSOD xảy ra trực tiếp thì không.

Có vẻ như bạn có các trang lỗi máy chủ được thiết lập đúng. Bạn chỉ cần phân biệt các trang lỗi máy chủ điển hình! = WSODs. Các trang lỗi máy chủ có thể được kích hoạt do tắc nghẽn tài nguyên và lưu lượng truy cập cao, nhưng bạn thực sự không nên có WSOD xảy ra trong quá trình sản xuất. Chúng thường xảy ra do mã hóa, tối ưu hóa hoặc cấu hình kém. Nếu bạn vẫn thấy WSOD, trước tiên hãy đảm bảo bạn tìm thấy (và giải quyết) nguyên nhân cốt lõi của vấn đề, trái ngược với việc cố gắng áp dụng hỗ trợ băng tần cho nó.


4
Cảm ơn câu trả lời của bạn. Bạn hoàn toàn đúng về nguyên nhân gốc / triệu chứng điều trị. Tuy nhiên, điều này không liên quan đến nhu cầu của các trang lỗi tốt vì thực tế là trong suốt tuổi thọ của dịch vụ, các lỗi sẽ xảy ra và trong các tình huống đó, luôn luôn tốt hơn để truyền đạt tình huống cho người dùng thay vì với các trang trống hoặc đen chung chung trang "lỗi máy chủ". Twitter cá voi thất bại là một ví dụ. Điều đó không loại bỏ sự cần thiết cho hồ sơ lỗi chuyên nghiệp, nhưng tạm thời, làm cho người dùng bớt tức giận.
Tommi Forsström

1
Ngoài ra, trong trường hợp này, không cần phân biệt giữa các lớp mà lỗi xuất phát (miễn là bên dưới máy chủ http) vì tôi chỉ cần một cơ chế bắt tất cả các lỗi trong lớp ứng dụng, cho dù đó là sự cố cơ sở dữ liệu , ai đó cam kết mã tào lao (và vượt qua phạm vi kiểm tra của chúng tôi) và bất kỳ tình huống lỗi bất ngờ nào có thể hiểu được khác. Nhưng như đã cập nhật trong câu hỏi, điều này không liên quan đến tôi vào lúc này vì đám mây dev của Acquia không hỗ trợ tùy chỉnh các trang lỗi 500-series vào lúc này.
Tommi Forsström

"Đám mây dev của Acquia không hỗ trợ tùy chỉnh các trang lỗi 500-series tại thời điểm này." Aww shucks, đó là điều tốt để biết.
barista nghiệp dư

Mặc dù đó gần như là con ruồi duy nhất trong thuốc mỡ với Dev Cloud hùng mạnh của Acquia và họ cũng có thể thực hiện điều này trong tương lai gần. Tôi không thể nói đủ cao cho Dev Cloud. Đó là một nền tảng tuyệt vời để chạy các dịch vụ Drupal trên!
Tommi Forsström

1

Bạn đang nhận được WSOD vì bạn đã tắt báo cáo lỗi trong php.ini. Đây là một vấn đề bảo mật - nếu bạn gặp lỗi và hacker thấy đó là gì, anh ta có thể sử dụng nó để hack trang web.

Tuy nhiên, nếu bạn muốn chặn lỗi, bạn cần bật hiển thị các lỗi trong php.ini (ví dụ này sẽ chỉ hiển thị các lỗi nghiêm trọng):

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

Và sau đó, bạn có thể đặt các tài liệu lỗi trong tệp htaccess:

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

Ngoài ra, bạn có thể chỉ định các lỗi trong tệp settings.php của Drupal .

Trong NGINX:

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

Vì bạn đang chạy Apache trong MAMP, hãy đặt nó trong .htaccess. Hãy nhớ rằng AllowOverridetrong cấu hình apache nên được bật (thường là vậy).


thiết lập một lệnh ErrorDocumentcho 500 phản hồi trong Drupal không hoạt động trong thử nghiệm của tôi
cdmo

500 lỗi thường không thể được đặt trong Drupal. Chúng cần được đặt trước Drupal - .htaccess nếu sử dụng Apache. Trong NGINX - xem vé cập nhật.
Alexei Rayu

Ý tôi là thế Bạn đã có thể nhận được một lệnh ErrorDocument cho 500 lỗi được đặt trong htaccess hoặc cấu hình vhost để thực sự hoạt động cho một trang web Drupal chưa? Những chỉ thị đó bị bỏ qua theo kinh nghiệm của tôi, Drupal đảm nhận việc xử lý lỗi.
cdmo

0

Bạn đã bật báo cáo lỗi? (admin / config / Development / log -> Đặt tất cả các thông báo cho các thông báo Lỗi hiển thị )

Theo mặc định, Drupal hiển thị WSOD như một tính năng bảo mật.


Hài hước lắm, điều đó đã được bật và tôi vẫn nhận được WSOD.
Tommi Forsström

Trong trường hợp đó, đó có thể là sự cố MAMP, không phải là sự cố Drupal. Hãy thử bật báo cáo lỗi trong php.ini ( forum.mamp.info/viewtopic.php?f=2&t=8077 ) Hiển thị lỗi bị tắt trong MAMP theo mặc định.
Patrick Kenny

1
Tôi có thể nhận được lỗi php hiển thị tốt. Đó không thực sự là vấn đề. Tôi muốn có thể hiển thị một cái gì đó thân thiện khi xảy ra lỗi, như Fail Whale của Twitter. Đó là điều tôi không thể thực hiện được: các trang lỗi tùy chỉnh cho các lỗi 500-series.
Tommi Forsström

0

Tôi đoán câu trả lời là "đọc tài liệu", xem https://www.drupal.org/node/195435

Vì vậy, về cơ bản, bạn có thể tạo các tệp mẫu có tên maintenance-page.tpl.phpmaintenance-page--offline.tpl.phpmã cứng một số cài đặt trong settings.php.

BIÊN TẬP:

Dường như không quan trọng mức độ nào error_reportingđược đặt thành hoặc liệu bạn đã đặt display_errorsthành onhay off. Khi bạn có một maintenance-page--offline.tpl.phptệp tại chỗ, Drupal sẽ hiển thị trang này khi cơ sở dữ liệu biến mất. Cũng không quan trọng những gì bạn đã đặt ở /admin/config/development/loggingphía quản trị viên. Nếu bạn chỉ có lỗi cú pháp, đó là tình huống của OP, thì thực tế sẽ không kích hoạt 500, đó là lỗi 200 với lỗi PHP được hiển thị hoặc ẩn dựa trên php.ini display_errortập hợp. Không có cách nào, mà tôi biết, ngoài việc thêm logic xử lý lỗi tùy chỉnh trong suốt mã tùy chỉnh của bạn khi cần.


Không chắc chắn tại sao tôi bị từ chối ở đây, đây là câu trả lời tôi đang tìm kiếm khi tôi đặt tiền thưởng. Một cái khác không dành cho OP, bạn cũng có thể đặt error_prepend và chắp thêm vào các thông báo lỗi PHP tiêu chuẩn nếu bạn muốn xây dựng thêm trang lỗi tiêu chuẩn của mình.
cdmo

0

Để thay thế tất cả WSOD bằng một thứ khác sẽ yêu cầu hack lõi: bạn không muốn làm điều này. Drupal định nghĩa các trình xử lý lỗi của riêng nó trong bootstrap.inc và error.inc. Nếu bạn gặp rắc rối với mã đó, bạn sẽ phải đảm bảo rằng bạn đã tính đến tất cả những điều có thể sai khi thực thi đạt đến giai đoạn này (không có cơ sở dữ liệu, không có công cụ chủ đề, không có chủ đề, không có cấu hình, v.v.).


Bạn đã bao giờ thử sử dụng các tùy chọn error_append và error_prepend của PHP chưa? Mặc dù thông báo lỗi vẫn hiển thị, nhưng có vẻ như bạn có thể cung cấp trải nghiệm 500 đẹp hơn (được cấp, không phải tất cả các lỗi PHP tạo màn hình trắng về mặt kỹ thuật gây ra phản hồi 500, giống như nhiều lỗi cú pháp.)
cdmo

Thật. Dù bằng cách nào cũng đưa bạn đến cùng một điểm chung: bạn không thể làm điều đó.
acrosman

0

Tôi đã thực hiện một dự án hộp cát để làm điều này.

Tôi đã có thể thực hiện điều này bằng cách mở rộng HttpExceptionSubscriberBase trong /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','');
      }


    }
?>

Và bạn sẽ cần thêm dịch vụ trong module.service.yml của bạn

services:
  five_hundred.:
    class: Drupal\five_hundred\EventSubscriber\five_hundredEventSubscriber
    arguments: ['@request_stack']
    tags:
      - { name: event_subscriber }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.