Merge "Pass Job success status to teardown callbacks"
[lhc/web/wiklou.git] / includes / exception / MWExceptionRenderer.php
index f455191..8fdc417 100644 (file)
@@ -28,18 +28,13 @@ class MWExceptionRenderer {
        const AS_PRETTY = 2; // show as HTML
 
        /**
-        * @param Exception $e Original exception
+        * @param Exception|Throwable $e Original exception
         * @param integer $mode MWExceptionExposer::AS_* constant
-        * @param Exception|null $eNew New exception from attempting to show the first
+        * @param Exception|Throwable|null $eNew New exception from attempting to show the first
         */
-       public static function output( Exception $e, $mode, Exception $eNew = null ) {
+       public static function output( $e, $mode, $eNew = null ) {
                global $wgMimeType;
 
-               if ( $e instanceof DBConnectionError ) {
-                       self::reportOutageHTML( $e );
-                       return;
-               }
-
                if ( defined( 'MW_API' ) ) {
                        // Unhandled API exception, we can't be sure that format printer is alive
                        self::header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $e ) );
@@ -47,9 +42,13 @@ class MWExceptionRenderer {
                } elseif ( self::isCommandLine() ) {
                        self::printError( self::getText( $e ) );
                } elseif ( $mode === self::AS_PRETTY ) {
-                       self::statusHeader( 500 );
-                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
-                       self::reportHTML( $e );
+                       if ( $e instanceof DBConnectionError ) {
+                               self::reportOutageHTML( $e );
+                       } else {
+                               self::statusHeader( 500 );
+                               self::header( "Content-Type: $wgMimeType; charset=utf-8" );
+                               self::reportHTML( $e );
+                       }
                } else {
                        if ( $eNew ) {
                                $message = "MediaWiki internal error.\n\n";
@@ -88,12 +87,12 @@ class MWExceptionRenderer {
         *
         * Called by MWException for b/c
         *
-        * @param Exception $e
+        * @param Exception|Throwable $e
         * @param string $name Class name of the exception
         * @param array $args Arguments to pass to the callback functions
         * @return string|null String to output or null if any hook has been called
         */
-       public static function runHooks( Exception $e, $name, $args = [] ) {
+       public static function runHooks( $e, $name, $args = [] ) {
                global $wgExceptionHooks;
 
                if ( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) {
@@ -129,20 +128,18 @@ class MWExceptionRenderer {
        }
 
        /**
-        * @param Exception $e
+        * @param Exception|Throwable $e
         * @return bool Should the exception use $wgOut to output the error?
         */
-       private static function useOutputPage( Exception $e ) {
+       private static function useOutputPage( $e ) {
                // Can the extension use the Message class/wfMessage to get i18n-ed messages?
-               $useMessageCache = ( $GLOBALS['wgLang'] instanceof Language );
                foreach ( $e->getTrace() as $frame ) {
                        if ( isset( $frame['class'] ) && $frame['class'] === 'LocalisationCache' ) {
-                               $useMessageCache = false;
+                               return false;
                        }
                }
 
                return (
-                       $useMessageCache &&
                        !empty( $GLOBALS['wgFullyInitialised'] ) &&
                        !empty( $GLOBALS['wgOut'] ) &&
                        !defined( 'MEDIAWIKI_INSTALL' )
@@ -152,9 +149,9 @@ class MWExceptionRenderer {
        /**
         * Output the exception report using HTML
         *
-        * @param Exception $e
+        * @param Exception|Throwable $e
         */
-       private static function reportHTML( Exception $e ) {
+       private static function reportHTML( $e ) {
                global $wgOut, $wgSitename;
 
                if ( self::useOutputPage( $e ) ) {
@@ -172,6 +169,10 @@ class MWExceptionRenderer {
                        if ( $hookResult ) {
                                $wgOut->addHTML( $hookResult );
                        } else {
+                               // Show any custom GUI message before the details
+                               if ( $e instanceof MessageSpecifier ) {
+                                       $wgOut->addHTML( Message::newFromSpecifier( $e )->escaped() );
+                               }
                                $wgOut->addHTML( self::getHTML( $e ) );
                        }
 
@@ -204,19 +205,19 @@ class MWExceptionRenderer {
         * backtrace to the error, otherwise show a message to ask to set it to true
         * to show that information.
         *
-        * @param Exception $e
+        * @param Exception|Throwable $e
         * @return string Html to output
         */
-       private static function getHTML( Exception $e ) {
+       public static function getHTML( $e ) {
                if ( self::showBackTrace( $e ) ) {
-                       return '<p>' .
+                       $html = "<div class=\"errorbox\"><p>" .
                                nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $e ) ) ) .
                                '</p><p>Backtrace:</p><p>' .
                                nl2br( htmlspecialchars( MWExceptionHandler::getRedactedTraceAsString( $e ) ) ) .
-                               "</p>\n";
+                               "</p></div>\n";
                } else {
                        $logId = WebRequest::getRequestId();
-                       return "<div class=\"errorbox\">" .
+                       $html = "<div class=\"errorbox\">" .
                                '[' . $logId . '] ' .
                                gmdate( 'Y-m-d H:i:s' ) . ": " .
                                self::msg( "internalerror-fatal-exception",
@@ -229,6 +230,8 @@ class MWExceptionRenderer {
                        "at the bottom of LocalSettings.php to show detailed " .
                        "debugging information. -->";
                }
+
+               return $html;
        }
 
        /**
@@ -250,10 +253,10 @@ class MWExceptionRenderer {
        }
 
        /**
-        * @param Exception $e
+        * @param Exception|Throwable $e
         * @return string
         */
-       private function getText( Exception $e ) {
+       private static function getText( $e ) {
                if ( self::showBackTrace( $e ) ) {
                        return MWExceptionHandler::getLogMessage( $e ) .
                                "\nBacktrace:\n" .
@@ -265,10 +268,10 @@ class MWExceptionRenderer {
        }
 
        /**
-        * @param Exception $e
+        * @param Exception|Throwable $e
         * @return bool
         */
-       private static function showBackTrace( Exception $e ) {
+       private static function showBackTrace( $e ) {
                global $wgShowExceptionDetails, $wgShowDBErrorBacktrace;
 
                return (
@@ -320,9 +323,9 @@ class MWExceptionRenderer {
        }
 
        /**
-        * @param Exception $e
+        * @param Exception|Throwable $e
         */
-       private static function reportOutageHTML( Exception $e ) {
+       private static function reportOutageHTML( $e ) {
                global $wgShowDBErrorBacktrace, $wgShowHostnames, $wgShowSQLErrors;
 
                $sorry = htmlspecialchars( self::msg(