Page MenuHomePhabricator

ApiBlock throws exception when re-blocking non-blocked user
Closed, ResolvedPublic

Description

ApiBlock returns the following error instead of a proper JSON result when re-blocking a user who isn't already blocked:

"Catchable fatal error: Argument 1 passed to Block::equals() must be an instance of Block, null given, called in /var/www/w24/includes/specials/SpecialBlock.php on line 725 and defined in /var/www/w24/includes/Block.php on line 192"

Event Timeline

RobinHood70 raised the priority of this task from to Needs Triage.
RobinHood70 updated the task description. (Show Details)
RobinHood70 subscribed.

Not really an API bug, SpecialBlock shouldn't be throwing an exception in the first place.

What's going on here is this:

  1. User::loadFromDatabase() auto-starts a transaction on master, if User::loadFromCache() misses.
  2. Block::insert() calls Block::purgeExpired() to try to delete expired blocks before inserting. But since Gerrit change 59794 that uses onTransactionIdle, so it doesn't actually purge anything due to the transaction in progress from step 1.
  3. Block::insert() tries to insert the new block, but fails due to the expired block that didn't get deleted in step 2.
  4. SpecialBlock::processForm() tries to load the existing block. But Block::newLoad sees that the block it's going to load is expired and so doesn't return it (it also deletes it from the database).
  5. So SpecialBlock::processForm() gets null for the current block, and boom.
Aklapper triaged this task as Medium priority.Feb 26 2015, 2:07 PM

Change 202255 had a related patch set uploaded (by Aaron Schulz):
Made Block::insert handle expired rows

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

Change 202255 merged by jenkins-bot:
Made Block::insert handle expired rows

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

Anomie assigned this task to aaron.

The fix here should be deployed to WMF wikis with 1.26wmf1, see https://www.mediawiki.org/wiki/MediaWiki_1.26/Roadmap for the schedule.