Page MenuHomePhabricator

Fatal error on Special:Recentchanges when days=800000 or higher
Closed, ResolvedPublicPRODUCTION ERROR

Description

how to reproduce:

https://he.wikipedia.org/w/index.php?title=Special:RecentChanges&days=30000000000&from=

log line:

{"id":"WBr9JQpAAD0AAL39ZhsAAABR","type":"TimestampException","file":"/srv/mediawiki/php-1.29.0-wmf.1/includes/libs/time/ConvertibleTimestamp.php","line":142,"message":"ConvertibleTimestamp::setTimestamp: Invalid timestamp - -2591998521782400","code":0,"ur

The error starts happening when days is more than 800,000. Anything lower works fine.

Event Timeline

Krinkle triaged this task as High priority.Jul 6 2017, 11:39 PM
Krinkle added a subscriber: Krinkle.
This comment was removed by Krinkle.
Krinkle lowered the priority of this task from High to Low.EditedJul 6 2017, 11:41 PM

Confirmed. Fatal error on https://he.wikipedia.org/w/index.php?title=%D7%9E%D7%99%D7%95%D7%97%D7%93:%D7%A9%D7%99%D7%A0%D7%95%D7%99%D7%99%D7%9D_%D7%90%D7%97%D7%A8%D7%95%D7%A0%D7%99%D7%9D&days=30000000000&from=

Internal error
[WV7GqwpAEK0AABLho7gAAAAQ] 2017-07-06 23:24:27: Fatal exception of type "Wikimedia\Timestamp\TimestampException"

From Logstash
Wikimedia\Timestamp\ConvertibleTimestamp::setTimestamp: Invalid timestamp - -2591998500614400

t exception.trace	   	#0 /srv/mediawiki/php-1.30.0-wmf.7/vendor/wikimedia/timestamp/src/ConvertibleTimestamp.php(68): Wikimedia\Timestamp\ConvertibleTimestamp->setTimestamp(integer)
#1 /srv/mediawiki/php-1.30.0-wmf.7/includes/libs/rdbms/database/Database.php(2992): Wikimedia\Timestamp\ConvertibleTimestamp->__construct(integer)
#2 /srv/mediawiki/php-1.30.0-wmf.7/includes/specials/SpecialRecentchanges.php(379): Wikimedia\Rdbms\Database->timestamp(integer)
#3 /srv/mediawiki/php-1.30.0-wmf.7/includes/specialpage/ChangesListSpecialPage.php(582): SpecialRecentChanges->buildQuery(array, array, array, array, array, FormOptions)
#4 /srv/mediawiki/php-1.30.0-wmf.7/includes/specialpage/ChangesListSpecialPage.php(520): ChangesListSpecialPage->getRows()
#5 /srv/mediawiki/php-1.30.0-wmf.7/includes/specials/SpecialRecentchanges.php(167): ChangesListSpecialPage->execute(NULL)
#6 /srv/mediawiki/php-1.30.0-wmf.7/includes/specialpage/SpecialPage.php(522): SpecialRecentChanges->execute(NULL)
#7 /srv/mediawiki/php-1.30.0-wmf.7/includes/specialpage/SpecialPageFactory.php(579): SpecialPage->run(NULL)
#8 /srv/mediawiki/php-1.30.0-wmf.7/includes/MediaWiki.php(287): SpecialPageFactory::executePath(Title, RequestContext)
#9 /srv/mediawiki/php-1.30.0-wmf.7/includes/MediaWiki.php(862): MediaWiki->performRequest()
#10 /srv/mediawiki/php-1.30.0-wmf.7/includes/MediaWiki.php(523): MediaWiki->main()
#11 /srv/mediawiki/php-1.30.0-wmf.7/index.php(43): MediaWiki->run()
#12 /srv/mediawiki/w/index.php(3): include(string)
#13 {main}
class SpecialRecentchanges { protected function buildQuery( .. ) {
		/ Calculate cutoff
		$cutoff_unixtime = time() - ( $opts['days'] * 86400 );
		$cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
		$cutoff = $dbr->timestamp( $cutoff_unixtime ); # <!-- line 379

		$fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
		if ( $fromValid && $opts['from'] > wfTimestamp( TS_MW, $cutoff ) ) {
			$cutoff = $dbr->timestamp( $opts['from'] );

I can reproduce it in isolation.

eval
$opts = [ 'days' => 30000 ];
$cutoff_unixtime = time() - ( $opts['days'] * 86400 );
$cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
$t = new Wikimedia\Timestamp\ConvertibleTimestamp( $cutoff_unixtime );
echo $t;
#> -1092614400
echo $t->getTimestamp( TS_MW );
#> 19350519000000

$opts = [ 'days' => 700000 ];
$cutoff_unixtime = time() - ( $opts['days'] * 86400 );$cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
$t = new Wikimedia\Timestamp\ConvertibleTimestamp( $cutoff_unixtime );
echo $t->getTimestamp( TS_MW );
#> 01001224000000

$opts = [ 'days' => 800000 ];
$cutoff_unixtime = time() - ( $opts['days'] * 86400 );$cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
$t = new Wikimedia\Timestamp\ConvertibleTimestamp( $cutoff_unixtime );
echo $t->getTimestamp( TS_MW );
#> Caught exception Wikimedia\Timestamp\TimestampException:
#> The timestamp cannot be represented in the specified format

$opts = [ 'days' => 30000000000 ];
$cutoff_unixtime = time() - ( $opts['days'] * 86400 );
$cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
$t = new Wikimedia\Timestamp\ConvertibleTimestamp( $cutoff_unixtime );
#> Caught exception Wikimedia\Timestamp\TimestampException:
#> Invalid timestamp - -2591998500614400

Note, this is not a problem with the database or with data from recent changes. The error is not caused by the processing of recent changes, rather, the error happens much earlier (which is why it responds so quickly).

Before we query the recent changes database, we first convert days to a normal timestamp as offset for the to-be query This converting of the days parameter to a timestamp is what fails.

Krinkle renamed this task from fatal : invalid time stamp in recent changes to Fatal error on Special:Recentchanges when days=800000 or higher.Jul 6 2017, 11:44 PM
Krinkle updated the task description. (Show Details)

Change 367846 had a related patch set uploaded (by Catrope; owner: Catrope):
[mediawiki/core@master] Cap 'days' param in RC/Watchlist at $wgRCMaxAge

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

Krinkle assigned this task to Catrope.

Change 367846 merged by jenkins-bot:
[mediawiki/core@master] Cap 'days' param in RC/Watchlist at $wgRCMaxAge

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

mmodell changed the subtype of this task from "Task" to "Production Error".Aug 28 2019, 11:11 PM