X-Git-Url: https://git.cyclocoop.org/%7B%24admin_url%7Dmembres/modifier.php?a=blobdiff_plain;f=includes%2Fexception%2FMWExceptionHandler.php;h=5ea935982668091c6257bb060222b9ea64212fe9;hb=69217704148a5751754fb1b9587e7f6d5c774b13;hp=9db04cbf6d7dd45ab32ee690f9bb7dd565809541;hpb=239b0c772a3cf4dc2160e2c36c2813cd705adb50;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/exception/MWExceptionHandler.php b/includes/exception/MWExceptionHandler.php index 9db04cbf6d..5ea9359826 100644 --- a/includes/exception/MWExceptionHandler.php +++ b/includes/exception/MWExceptionHandler.php @@ -24,12 +24,24 @@ */ class MWExceptionHandler { + protected static $reservedMemory; + protected static $fatalErrorTypes = array( + E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, + /* HHVM's FATAL_ERROR level */ 16777217, + ); + /** * Install handlers with PHP. */ public static function installHandler() { set_exception_handler( array( 'MWExceptionHandler', 'handleException' ) ); set_error_handler( array( 'MWExceptionHandler', 'handleError' ) ); + + // Reserve 16k of memory so we can report OOM fatals + self::$reservedMemory = str_repeat( ' ', 16384 ); + register_shutdown_function( + array( 'MWExceptionHandler', 'handleFatalError' ) + ); } /** @@ -130,7 +142,7 @@ class MWExceptionHandler { * * try { * ... - * } catch ( MWException $e ) { + * } catch ( Exception $e ) { * $e->report(); * } catch ( Exception $e ) { * echo $e->__toString(); @@ -194,6 +206,9 @@ class MWExceptionHandler { case E_USER_DEPRECATED: $levelName = 'Deprecated'; break; + case /* HHVM's FATAL_ERROR */ 16777217: + $levelName = 'Fatal'; + break; default: $levelName = 'Unknown error'; break; @@ -207,6 +222,44 @@ class MWExceptionHandler { return false; } + + /** + * Look for a fatal error as the cause of the request termination and log + * as an exception. + * + * Special handling is included for missing class errors as they may + * indicate that the user needs to install 3rd-party libraries via + * Composer or other means. + * + * @since 1.25 + */ + public static function handleFatalError() { + self::$reservedMemory = null; + $lastError = error_get_last(); + + if ( $lastError && + isset( $lastError['type'] ) && + in_array( $lastError['type'], self::$fatalErrorTypes ) + ) { + $msg = "Fatal Error: {$lastError['message']}"; + // HHVM: Class undefined: foo + // PHP5: Class 'foo' not found + if ( preg_match( "/Class (undefined: \w+|'\w+' not found)/", + $lastError['message'] + ) ) { + $msg = <<mediawiki.org for help on installing the required components. +TXT; + } + $e = new ErrorException( $msg, 0, $lastError['type'] ); + self::logError( $e ); + } + } + /** * Generate a string representation of an exception's stack trace * @@ -440,5 +493,10 @@ class MWExceptionHandler { } else { wfDebugLog( 'error', $log ); } + + $json = self::jsonSerializeException( $e, false, FormatJson::ALL_OK ); + if ( $json !== false ) { + wfDebugLog( 'error-json', $json, 'private' ); + } } }