Currently, any critical exceptions thrown from any DeferrableUpdate are silently ignored by DeferredUpdates::runUpdate.
Exceptions thrown by a DeferrableUpdate cause a code 500 response (if still possible), and should go to the error log per default. They should also cause unit tests to fail.
Critical exceptions (such as RuntimeExceptions or LogicExceptions) thrown by a DeferrableUpdate are silently ignored. They are only visible in the debug log if the "exception" channel is explcitly enabled.
- DeferredUpdates::runUpdate calls MWExceptionHandler::rollbackMasterChangesAndLog
- MWExceptionHandler::rollbackMasterChangesAndLog calls MWExceptionHandler::logException, which calls error() on a Logger returned by LoggerFactory::getInstance( 'exception' ).
- The logger used by MWExceptionHandler is per default a LegacyLogger. LegacyLogger::error forwards to LegacyLogger::log, which, per default, ends up calling MWDebug::debugMsg, but not LegacyLogger::emit(), because shouldEmit() returns false.
- shouldEmit() returns false unless $wgDebugLogGroups contains 'exception', which is this LegacyLogger's default channel as per the call to LoggerFactory::getInstance().
- LegacyLogger::log should default to the wfErrorLog channel if $level is >= LogLevel::ERROR. In addition, MWDebug::warning should be called instead of MWDebug::debugMsg if $level is >= LogLevel::WARNING.
- It's unclear if level LogLevel::WARNING should be considered a "developer warning" which just causes tests to fail, or a "production warning" that also goes into error logs. In any case, unit tests should fail when warning are triggered (unless the warnign was specifically suppressed).
- Alternatively, if the behavior of LegacyLogger should not be changed, DeferredUpdates::runUpdate should be changed to call wfLogWarning() for all exceptions that are not ErrorPageErrors (and maybe even for them).