X-Git-Url: https://git.cyclocoop.org/%242?a=blobdiff_plain;f=includes%2Fexception%2FMWExceptionHandler.php;h=a2ec391dc1a89a707f6ee5e71c3de438d826592c;hb=c2b3638a975c6b159a78c5e1f00481b01014fd66;hp=433274e3395681590b6cdc9811952dd8afdcc7e7;hpb=b1dfb00704a39474a7b69ecf464227502c7aa57c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/exception/MWExceptionHandler.php b/includes/exception/MWExceptionHandler.php index 433274e339..a2ec391dc1 100644 --- a/includes/exception/MWExceptionHandler.php +++ b/includes/exception/MWExceptionHandler.php @@ -83,29 +83,32 @@ class MWExceptionHandler { } /** - * If there are any open database transactions, roll them back and log - * the stack trace of the exception that should have been caught so the - * transaction could be aborted properly. + * Roll back any open database transactions and log the stack trace of the exception + * + * This method is used to attempt to recover from exceptions * * @since 1.23 * @param Exception|Throwable $e */ public static function rollbackMasterChangesAndLog( $e ) { $services = MediaWikiServices::getInstance(); - if ( $services->isServiceDisabled( 'DBLoadBalancerFactory' ) ) { - return; // T147599 + if ( !$services->isServiceDisabled( 'DBLoadBalancerFactory' ) ) { + // Rollback DBs to avoid transaction notices. This might fail + // to rollback some databases due to connection issues or exceptions. + // However, any sane DB driver will rollback implicitly anyway. + try { + $services->getDBLoadBalancerFactory()->rollbackMasterChanges( __METHOD__ ); + } catch ( DBError $e2 ) { + // If the DB is unreacheable, rollback() will throw an error + // and the error report() method might need messages from the DB, + // which would result in an exception loop. PHP may escalate such + // errors to "Exception thrown without a stack frame" fatals, but + // it's better to be explicit here. + self::logException( $e2, self::CAUGHT_BY_HANDLER ); + } } - $lbFactory = $services->getDBLoadBalancerFactory(); - if ( $lbFactory->hasMasterChanges() ) { - $logger = LoggerFactory::getInstance( 'Bug56269' ); - $logger->warning( - 'Exception thrown with an uncommited database transaction: ' . - self::getLogMessage( $e ), - self::getLogContext( $e ) - ); - } - $lbFactory->rollbackMasterChanges( __METHOD__ ); + self::logException( $e, self::CAUGHT_BY_HANDLER ); } /** @@ -123,25 +126,8 @@ class MWExceptionHandler { * @param Exception|Throwable $e */ public static function handleException( $e ) { - try { - // Rollback DBs to avoid transaction notices. This may fail - // to rollback some DB due to connection issues or exceptions. - // However, any sane DB driver will rollback implicitly anyway. - self::rollbackMasterChangesAndLog( $e ); - } catch ( DBError $e2 ) { - // If the DB is unreacheable, rollback() will throw an error - // and the error report() method might need messages from the DB, - // which would result in an exception loop. PHP may escalate such - // errors to "Exception thrown without a stack frame" fatals, but - // it's better to be explicit here. - self::logException( $e2, self::CAUGHT_BY_HANDLER ); - } - - self::logException( $e, self::CAUGHT_BY_HANDLER ); + self::rollbackMasterChangesAndLog( $e ); self::report( $e ); - - // Exit value should be nonzero for the benefit of shell jobs - exit( 1 ); } /** @@ -455,6 +441,24 @@ TXT; return "[$id] $url $type from line $line of $file: $message"; } + /** + * Get a normalised message for formatting with PSR-3 log event context. + * + * Must be used together with `getLogContext()` to be useful. + * + * @since 1.30 + * @param Exception|Throwable $e + * @return string + */ + public static function getLogNormalMessage( $e ) { + $type = get_class( $e ); + $file = $e->getFile(); + $line = $e->getLine(); + $message = $e->getMessage(); + + return "[{exception_id}] {exception_url} $type from line $line of $file: $message"; + } + /** * @param Exception|Throwable $e * @return string @@ -482,6 +486,7 @@ TXT; return [ 'exception' => $e, 'exception_id' => WebRequest::getRequestId(), + 'exception_url' => self::getURL() ?: '[no req]', 'caught_by' => $catcher ]; } @@ -609,7 +614,7 @@ TXT; if ( !( $e instanceof MWException ) || $e->isLoggable() ) { $logger = LoggerFactory::getInstance( 'exception' ); $logger->error( - self::getLogMessage( $e ), + self::getLogNormalMessage( $e ), self::getLogContext( $e, $catcher ) ); @@ -630,7 +635,7 @@ TXT; * @param ErrorException $e * @param string $channel * @param string $level - */ + */ protected static function logError( ErrorException $e, $channel, $level = LogLevel::ERROR ) { @@ -643,7 +648,7 @@ TXT; $logger = LoggerFactory::getInstance( $channel ); $logger->log( $level, - self::getLogMessage( $e ), + self::getLogNormalMessage( $e ), self::getLogContext( $e, $catcher ) ); }