Page MenuHomePhabricator

ApiQueryContentTranslation: Call to a member function getName() on null
Closed, ResolvedPublic

Description

Observed in a logstash:

  • Branch: php-1.35.0-wmf.31 (testwiki)
  • User impact: unknown
  • Log messages:
[670f6482-b077-4e84-9801-1c96d03e57f5] /w/api.php?action=query&format=json&list=contenttranslation&sourcetitle=Lockdown&from=en&to=pt   Error from line 165 of /srv/mediawiki/php-1.35.0-wmf.31/extensions/ContentTranslation/api/ApiQueryContentTranslation.php: Call to a member function getName() on null
/srv/mediawiki/php-1.35.0-wmf.31/extensions/ContentTranslation/api/ApiQueryContentTranslation.php(69): ApiQueryContentTranslation->find(ContentTranslation\TranslationWork, ContentTranslation\Translator)
#1 /srv/mediawiki/php-1.35.0-wmf.31/extensions/ContentTranslation/api/ApiQueryContentTranslation.php(25): ApiQueryContentTranslation->run()
#2 /srv/mediawiki/php-1.35.0-wmf.31/includes/api/ApiQuery.php(263): ApiQueryContentTranslation->execute()
#3 /srv/mediawiki/php-1.35.0-wmf.31/includes/api/ApiMain.php(1580): ApiQuery->execute()
#4 /srv/mediawiki/php-1.35.0-wmf.31/includes/api/ApiMain.php(523): ApiMain->executeAction()
#5 /srv/mediawiki/php-1.35.0-wmf.31/includes/api/ApiMain.php(494): ApiMain->executeActionWithErrorHandling()
#6 /srv/mediawiki/php-1.35.0-wmf.31/api.php(84): ApiMain->execute()
#7 /srv/mediawiki/w/api.php(3): require(string)
#8 {main}

Summary: Fixed CX to handle the case when another user tried to translate an article which is being translated by an unknown user

QA plan

Affected project: test.wikipedia.org
Pre-deployment testing: skip
Post-deployment testing:

  • Try to translate article Lockdown from en to pt on test.wikipedia.org
  • Monitor Logstash for 7 days after deployment to confirm error is gone

Outcome

Content Translation gracefully handles an edge case when trying to translate a page which is already being translated by another, unknown user

Event Timeline

This is in the code path that is showing "this translation is work in progress by user X", where we cannot identify who is X, likely due to earlier database corruption (due to code issue, not data reliability issue).

// Add name and gender information to the returned result. The UI can use this
// to display the conflict message.
$globalUserId = $translation->getData()['lastUpdatedTranslator'];
$centralIdLookup = CentralIdLookup::factory();
// $user can be null, but should never happen in our case because
// we redirect translators to the target wiki, and they cannot do
// translations without logging in.
$user = $centralIdLookup->localUserFromCentralId( $globalUserId );
$gender = $services->getGenderCache()->getGenderOf( $user, __METHOD__ );

$translation->translation['translatorName'] = $user->getName(); // Fails on this line
$translation->translation['translatorGender'] = $gender;

localUserFromCentralId() can return null if the context user does not have permission to see the user returned by the method.
The doc here seems to not consider this case and just assume since the 'lastUpdatedTranslator' must have done some translations then they'll always be returned by localUserFromCentralId() for everybody. In this case, probably the username of the translator is hidden and so, even though they satisfy the doc assumption here (by being registered+done some trans), null is still returned due to the restriction on viewing the user.

// $user can be null, but should never happen in our case because
// we redirect translators to the target wiki, and they cannot do
// translations without logging in.

Change 595912 had a related patch set uploaded (by Nikerabbit; owner: Nikerabbit):
[mediawiki/extensions/ContentTranslation@master] ApiQueryContentTranslation: avoid fatals on getName

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

Change 595912 merged by jenkins-bot:
[mediawiki/extensions/ContentTranslation@master] ApiQueryContentTranslation: avoid fatals on getName

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

Is this similar or different case?

[ac0782a6-b6ac-4dd4-9bd1-c434695b13e0] /w/api.php?action=query&format=json&formatversion=2&meta=notifications&notsections=message&notformat=model&notlimit=25&notprop=list%7Ccount%7CseenTime&uselang=sv&notcrosswikisummary=1&notunreadfirst=1&notbundle=1&_=1591453607963   Error from line 61 of /srv/mediawiki/php-1.35.0-wmf.35/extensions/ContentTranslation/includes/DraftNotificationPresentationModel.php: Call to a member function getText() on null

It's not the same. Can you report it separately?

Did a query for "Error from line 165" for the last month and couldn't find any logs.
https://logstash.wikimedia.org/goto/f2ff43c0101ef84cc62e412cf5794c21

Avoid searching by line number as the code has changed in the above patch. For example, if the bug still happened, it would now likely come from line 167.

The significant parts of this one were "ApiQueryContentTranslation.php" or "ApiQueryContentTranslation.php: Call to a member function".

https://logstash.wikimedia.org/goto/ae33d183c6bd1d6cb5523c60a3100769

Here we can see that the error existed in early May (not seeing the old ones can also be an indicator that the query might be too specific), and that there were none after May 13.