Page MenuHomePhabricator

Fatal Error: Call to a member function disable() on a non-object (wfHttpError should check, if wgOut is an instance of OutputPage)
Closed, ResolvedPublic

Description

wfHttpError assumes, that $wgOut is an instance of OutputPage and runs ->disable() on it:
https://github.com/wikimedia/mediawiki/blob/74faccfa264fca219e08ae9cfb60a355ec2fac39/includes/GlobalFunctions.php#L2078

I had some fatal errors in my error_log of my production server, so i tracked the problem down, and it seems, that wfHttpError can be called, before wgOut is set, here a stack trace (because i can't reproduce this error myself, because it seems to occur only on api calls and only specific times (always, when the mysql user exceeded the max_user_connection limit, which is another problem. So i had to workaround to get a stack trace, because it's only a webspace hoster, no possibility to enable anything to log fatal error stack traces):

#0 and #1 are catching functions (called when wgOut isn't an instance of OutputPage in wfHttpError) to log the stack trace
#2 {wikiroot}/includes/exception/MWException.php(228): wfHttpError(500, 'Internal Server Error', 'DB connection error
')
#3 {wikiroot}/includes/exception/MWExceptionHandler.php(59): MWException->report()
#4 {wikiroot}/includes/exception/MWExceptionHandler.php(159): MWExceptionHandler->report(DBConnectionError::__set_state(array(
   'error' => 'User \'{user}\' has exceeded the \'max_user_connections\' resource (current value: 15) (127.0.0.1)',
   'db' => 
  DatabaseMysqli::__set_state(array(
     'lastKnownSlavePos' => NULL,
     'mFakeSlaveLag' => NULL,
     'mFakeMaster' => false,
     'serverVersion' => NULL,
     'mLastQuery' => '',
     'mDoneWrites' => false,
     'mPHPError' => 'mysqli::real_connect(): (42000/1226): User \'{user}\' has exceeded the \'max_user_connections\' resource (current value: 15)',
     'mServer' => '127.0.0.1',
     'mUser' => '{user}',
     'mPassword' => '{pass}',
     'mDBname' => '{db}',
     'mConn' => false,
     'mOpened' => false,
     'mTrxIdleCallbacks' => 
    array (
    ),
     'mTrxPreCommitCallbacks' => 
    array (
    ),
     'mTablePrefix' => '',
     'mSchema' => NULL,
     'mFlags' => 24,
     'mForeign' => false,
     'mErrorCount' => 0,
     'mLBInfo' => 
    array (
      'host' => '127.0.0.1',
      'user' => '{user}',
      'password' => '{pass}',
      'dbname' => '{db}',
      'type' => 'mysql',
      'load' => 1,
      'flags' => 16,
      'serverIndex' => 0,
    ),
     'mDefaultBigSelects' => NULL,
     'mSchemaVars' => false,
     'preparedArgs' => NULL,
     'htmlErrors' => '',
     'delimiter' => ';',
     'mTrxLevel' => 0,
     'mTrxShortId' => '',
     'mTrxTimestamp' => NULL,
     'mTrxFname' => NULL,
     'mTrxDoneWrites' => false,
     'mTrxAutomatic' => false,
     'mTrxAtomicLevels' => 
    SplStack::__set_state(array(
    )),
     'mTrxAutomaticAtomic' => false,
     'fileHandle' => NULL,
     'allViews' => NULL,
  )),
   'message' => 'DB connection error: User \'{user}\' has exceeded the \'max_user_connections\' resource (current value: 15) (127.0.0.1)',
   'string' => '',
   'code' => 0,
   'file' => '{wikiroot}/includes/db/Database.php',
   'line' => 1016,
   'trace' => 
  array (
    0 => 
    array (
      'file' => '{wikiroot}/includes/db/LoadBalancer.php',
      'line' => 783,
      'function' => 'reportConnectionError',
      'class' => 'DatabaseBase',
      'type' => '->',
      'args' => 
      array (
        0 => 'Unknown error (127.0.0.1)',
      ),
    ),
    1 => 
    array (
      'file' => '{wikiroot}/includes/db/LoadBalancer.php',
      'line' => 494,
      'function' => 'reportConnectionError',
      'class' => 'LoadBalancer',
      'type' => '->',
      'args' => 
      array (
      ),
    ),
    2 => 
    array (
      'file' => '{wikiroot}/includes/GlobalFunctions.php',
      'line' => 3567,
      'function' => 'getConnection',
      'class' => 'LoadBalancer',
      'type' => '->',
      'args' => 
      array (
        0 => -1,
        1 => 
        array (
        ),
        2 => false,
      ),
    ),
    3 => 
    array (
      'file' => '{wikiroot}/includes/cache/LocalisationCache.php',
      'line' => 1175,
      'function' => 'wfGetDB',
      'args' => 
      array (
        0 => -1,
      ),
    ),
    4 => 
    array (
      'file' => '{wikiroot}/includes/cache/LocalisationCache.php',
      'line' => 405,
      'function' => 'get',
      'class' => 'LCStoreDB',
      'type' => '->',
      'args' => 
      array (
        0 => 'de',
        1 => 'deps',
      ),
    ),
    5 => 
    array (
      'file' => '{wikiroot}/includes/cache/LocalisationCache.php',
      'line' => 451,
      'function' => 'isExpired',
      'class' => 'LocalisationCache',
      'type' => '->',
      'args' => 
      array (
        0 => 'de',
      ),
    ),
    6 => 
    array (
      'file' => '{wikiroot}/includes/cache/LocalisationCache.php',
      'line' => 327,
      'function' => 'initLanguage',
      'class' => 'LocalisationCache',
      'type' => '->',
      'args' => 
      array (
        0 => 'de',
      ),
    ),
    7 => 
    array (
      'file' => '{wikiroot}/includes/cache/LocalisationCache.php',
      'line' => 261,
      'function' => 'loadItem',
      'class' => 'LocalisationCache',
      'type' => '->',
      'args' => 
      array (
        0 => 'de',
        1 => 'fallback',
      ),
    ),
    8 => 
    array (
      'file' => '{wikiroot}/languages/Language.php',
      'line' => 4320,
      'function' => 'getItem',
      'class' => 'LocalisationCache',
      'type' => '->',
      'args' => 
      array (
        0 => 'de',
        1 => 'fallback',
      ),
    ),
    9 => 
    array (
      'file' => '{wikiroot}/languages/Language.php',
      'line' => 208,
      'function' => 'getFallbacksFor',
      'class' => 'Language',
      'type' => '::',
      'args' => 
      array (
        0 => 'de',
      ),
    ),
    10 => 
    array (
      'file' => '{wikiroot}/languages/Language.php',
      'line' => 167,
      'function' => 'newFromCode',
      'class' => 'Language',
      'type' => '::',
      'args' => 
      array (
        0 => 'de',
      ),
    ),
    11 => 
    array (
      'file' => '{wikiroot}/includes/Setup.php',
      'line' => 608,
      'function' => 'factory',
      'class' => 'Language',
      'type' => '::',
      'args' => 
      array (
        0 => 'de',
      ),
    ),
    12 => 
    array (
      'file' => '{wikiroot}/includes/WebStart.php',
      'line' => 121,
      'args' => 
      array (
        0 => '{wikiroot}/includes/Setup.php',
      ),
      'function' => 'require_once',
    ),
    13 => 
    array (
      'file' => '{wikiroot}/api.php',
      'line' => 43,
      'args' => 
      array (
        0 => '{wikiroot}/includes/WebStart.php',
      ),
      'function' => 'require',
    ),
  ),
   'previous' => NULL,
)))

Called URL. /api.php?hidebots=1&days=7&limit=50&action=feedrecentchanges&feedformat=atom

In Setup.php, wgContLang is set (L608) before wgOut is set (L628), which results in Fatal errors in some special cases.

Event Timeline

Florian renamed this task from wfHttpError should check, if wgOut is an instance of OutputPage to Fatal Error: Call to a member function disable() on a non-object (wfHttpError should check, if wgOut is an instance of OutputPage).
Florian raised the priority of this task from to Needs Triage.
Florian updated the task description. (Show Details)
Florian added a project: MediaWiki-General.
Florian set Security to None.
Florian added a subscriber: Florian.
Aklapper triaged this task as Medium priority.Jan 12 2015, 1:51 PM

Change 184486 had a related patch set uploaded (by Anomie):
Don't call $wgOut->disable() from wfHttpError if $wgOut isn't set up yet

https://gerrit.wikimedia.org/r/184486

Patch-For-Review

Change 184486 merged by jenkins-bot:
Don't call $wgOut->disable() from wfHttpError if $wgOut isn't set up yet

https://gerrit.wikimedia.org/r/184486

Florian claimed this task.