MWExceptionRenderer: Fix db error outage page
[lhc/web/wiklou.git] / includes / exception / MWExceptionRenderer.php
index 579b6ca..88b28df 100644 (file)
@@ -33,7 +33,7 @@ class MWExceptionRenderer {
 
        /**
         * @param Exception|Throwable $e Original exception
-        * @param integer $mode MWExceptionExposer::AS_* constant
+        * @param int $mode MWExceptionExposer::AS_* constant
         * @param Exception|Throwable|null $eNew New exception from attempting to show the first
         */
        public static function output( $e, $mode, $eNew = null ) {
@@ -47,13 +47,15 @@ class MWExceptionRenderer {
                        self::printError( self::getText( $e ) );
                } elseif ( $mode === self::AS_PRETTY ) {
                        self::statusHeader( 500 );
+                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
                        if ( $e instanceof DBConnectionError ) {
                                self::reportOutageHTML( $e );
                        } else {
-                               self::header( "Content-Type: $wgMimeType; charset=utf-8" );
                                self::reportHTML( $e );
                        }
                } else {
+                       self::statusHeader( 500 );
+                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
                        if ( $eNew ) {
                                $message = "MediaWiki internal error.\n\n";
                                if ( self::showBackTrace( $e ) ) {
@@ -90,7 +92,7 @@ class MWExceptionRenderer {
        private static function useOutputPage( $e ) {
                // Can the extension use the Message class/wfMessage to get i18n-ed messages?
                foreach ( $e->getTrace() as $frame ) {
-                       if ( isset( $frame['class'] ) && $frame['class'] === 'LocalisationCache' ) {
+                       if ( isset( $frame['class'] ) && $frame['class'] === LocalisationCache::class ) {
                                return false;
                        }
                }
@@ -128,7 +130,7 @@ class MWExceptionRenderer {
 
                        // Show any custom GUI message before the details
                        if ( $e instanceof MessageSpecifier ) {
-                               $wgOut->addHTML( Message::newFromSpecifier( $e )->escaped() );
+                               $wgOut->addHTML( Html::element( 'p', [], Message::newFromSpecifier( $e )->text() ) );
                        }
                        $wgOut->addHTML( self::getHTML( $e ) );
 
@@ -169,14 +171,15 @@ class MWExceptionRenderer {
                } else {
                        $logId = WebRequest::getRequestId();
                        $html = "<div class=\"errorbox mw-content-ltr\">" .
-                               '[' . $logId . '] ' .
-                               gmdate( 'Y-m-d H:i:s' ) . ": " .
-                               self::msg( "internalerror-fatal-exception",
-                                       "Fatal exception of type $1",
-                                       get_class( $e ),
-                                       $logId,
-                                       MWExceptionHandler::getURL()
-                               ) . "</div>\n" .
+                               htmlspecialchars(
+                                       '[' . $logId . '] ' .
+                                       gmdate( 'Y-m-d H:i:s' ) . ": " .
+                                       self::msg( "internalerror-fatal-exception",
+                                               "Fatal exception of type $1",
+                                               get_class( $e ),
+                                               $logId,
+                                               MWExceptionHandler::getURL()
+                               ) ) . "</div>\n" .
                                "<!-- " . wordwrap( self::getShowBacktraceError( $e ), 50 ) . " -->";
                }
 
@@ -211,7 +214,7 @@ class MWExceptionRenderer {
                                "\nBacktrace:\n" .
                                MWExceptionHandler::getRedactedTraceAsString( $e ) . "\n";
                } else {
-                       return self::getShowBacktraceError( $e );
+                       return self::getShowBacktraceError( $e ) . "\n";
                }
        }
 
@@ -242,7 +245,7 @@ class MWExceptionRenderer {
                        $vars[] = '$wgShowDBErrorBacktrace = true;';
                }
                $vars = implode( ' and ', $vars );
-               return "Set $vars at the bottom of LocalSettings.php to show detailed debugging information\n";
+               return "Set $vars at the bottom of LocalSettings.php to show detailed debugging information.";
        }
 
        /**
@@ -262,7 +265,7 @@ class MWExceptionRenderer {
        }
 
        /**
-        * @param integer $code
+        * @param int $code
         */
        private static function statusHeader( $code ) {
                if ( !headers_sent() ) {
@@ -291,7 +294,7 @@ class MWExceptionRenderer {
         * @param Exception|Throwable $e
         */
        private static function reportOutageHTML( $e ) {
-               global $wgShowDBErrorBacktrace, $wgShowHostnames, $wgShowSQLErrors;
+               global $wgShowDBErrorBacktrace, $wgShowHostnames, $wgShowSQLErrors, $wgSitename;
 
                $sorry = htmlspecialchars( self::msg(
                        'dberr-problems',
@@ -305,7 +308,7 @@ class MWExceptionRenderer {
                if ( $wgShowHostnames || $wgShowSQLErrors ) {
                        $info = str_replace(
                                '$1',
-                               Html::element( 'span', [ 'dir' => 'ltr' ], htmlspecialchars( $e->getMessage() ) ),
+                               Html::element( 'span', [ 'dir' => 'ltr' ], $e->getMessage() ),
                                htmlspecialchars( self::msg( 'dberr-info', '($1)' ) )
                        );
                } else {
@@ -316,8 +319,13 @@ class MWExceptionRenderer {
                }
 
                MessageCache::singleton()->disable(); // no DB access
-
-               $html = "<h1>$sorry</h1><p>$again</p><p><small>$info</small></p>";
+               $html = "<!DOCTYPE html>\n" .
+                               '<html><head>' .
+                               '<title>' .
+                               htmlspecialchars( $wgSitename ) .
+                               '</title>' .
+                               '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' .
+                               "</head><body><h1>$sorry</h1><p>$again</p><p><small>$info</small></p>";
 
                if ( $wgShowDBErrorBacktrace ) {
                        $html .= '<p>Backtrace:</p><pre>' .
@@ -326,7 +334,7 @@ class MWExceptionRenderer {
 
                $html .= '<hr />';
                $html .= self::googleSearchForm();
-
+               $html .= '</body></html>';
                echo $html;
        }