Page MenuHomePhabricator

Add "restore associated talk page" option to ApiUndelete
Closed, ResolvedPublic3 Estimated Story PointsFeature

Description

Similar to T263209 for ApiDelete: the undelete API module should have an option that allows the user to undelete the associated talk of non-talk pages. This will only permit restoring all revisions of the talk page.

Acceptance criteria

  • Add an undeletetalk parameter to the Undelete API
  • If subject page undeletion fails (i.e. it doesn't have deleted revisions), talk page undeletion should be aborted
  • If restoring the associated talk page fails, restoring the subject page should still happen but with a warning about the talk page failing
  • If the talk page exists but has some deleted revisions, undeletetalk should restore them.

Event Timeline

Daimona moved this task from New & TBD Tickets to Up Next on the Community-Tech board.
Daimona set the point value for this task to 3.

Change 747839 had a related patch set uploaded (by Dmaza; author: Daimona Eaytoy):

[mediawiki/core@master] ApiUndelete: add option to undelete associated talk page

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

Change 747839 merged by jenkins-bot:

[mediawiki/core@master] ApiUndelete: add option to undelete associated talk page

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

@dmaza I am getting an error undeleting some files on beta commons. I think it is related to the number of archived files (entries in filearchive).

For example:

The API response is:

{
    "error": {
        "code": "internal_api_error_InvalidArgumentException",
        "info": "[YkcQx@JzPJAbh3XaM4yBcAAAAFg] Exception caught: $key must be a string or an array",
        "errorclass": "InvalidArgumentException",
        "*": "InvalidArgumentException at /srv/mediawiki/php-master/includes/language/Message.php(245)\nfrom /srv/mediawiki/php-master/includes/language/Message.php(245)\n#0 /srv/mediawiki/php-master/includes/api/ApiMessage.php(88): Message->__construct(Status)\n#1 /srv/mediawiki/php-master/includes/api/ApiMessage.php(65): ApiMessage->__construct(Status, NULL, NULL)\n#2 /srv/mediawiki/php-master/includes/api/ApiUsageException.php(73): ApiMessage::create(Status, NULL, NULL)\n#3 /srv/mediawiki/php-master/includes/api/ApiBase.php(1445): ApiUsageException::newWithMessage(ApiUndelete, Status, NULL, NULL, NULL)\n#4 /srv/mediawiki/php-master/includes/api/ApiUndelete.php(114): ApiBase->dieWithError(Status)\n#5 /srv/mediawiki/php-master/includes/api/ApiMain.php(1898): ApiUndelete->execute()\n#6 /srv/mediawiki/php-master/includes/api/ApiMain.php(871): ApiMain->executeAction()\n#7 /srv/mediawiki/php-master/includes/api/ApiMain.php(842): ApiMain->executeActionWithErrorHandling()\n#8 /srv/mediawiki/php-master/api.php(90): ApiMain->execute()\n#9 /srv/mediawiki/php-master/api.php(45): wfApiMain()\n#10 /srv/mediawiki/w/api.php(3): require(string)\n#11 {main}"
    },
    "servedby": "deployment-mediawiki11"
}

Prettified it is:

InvalidArgumentException at /srv/mediawiki/php-master/includes/language/Message.php(245)
from /srv/mediawiki/php-master/includes/language/Message.php(245)
#0 /srv/mediawiki/php-master/includes/api/ApiMessage.php(88): Message->__construct(Status)
#1 /srv/mediawiki/php-master/includes/api/ApiMessage.php(65): ApiMessage->__construct(Status, NULL, NULL)
#2 /srv/mediawiki/php-master/includes/api/ApiUsageException.php(73): ApiMessage::create(Status, NULL, NULL)
#3 /srv/mediawiki/php-master/includes/api/ApiBase.php(1445): ApiUsageException::newWithMessage(ApiUndelete, Status, NULL, NULL, NULL)
#4 /srv/mediawiki/php-master/includes/api/ApiUndelete.php(114): ApiBase->dieWithError(Status)
#5 /srv/mediawiki/php-master/includes/api/ApiMain.php(1898): ApiUndelete->execute()
#6 /srv/mediawiki/php-master/includes/api/ApiMain.php(871): ApiMain->executeAction()
#7 /srv/mediawiki/php-master/includes/api/ApiMain.php(842): ApiMain->executeActionWithErrorHandling()
#8 /srv/mediawiki/php-master/api.php(90): ApiMain->execute()
#9 /srv/mediawiki/php-master/api.php(45): wfApiMain()
#10 /srv/mediawiki/w/api.php(3): require(string)
#11 {main}

I can also reproduce this locally (local docker sqlite), but only when the file has over 1000 archived files.

Locally, I checked out a commit from ~1 month ago (76ce3758bf4b68b695509688b431c8fae1f88072) and I could not reproduce the bug, instead I got the error:

{
    "error": {
        "code": "backend-fail-batchsize",
        "info": "The storage backend was given a batch of 1149 file operations; the limit is 1000 operations.",
        "*": "See http://localhost:8081/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/postorius/lists/mediawiki-api-announce.lists.wikimedia.org/> for notice of API deprecations and breaking changes."
    },
    "servedby": "15cefbfe7cc2"
}

I cannot reproduce this on test, for example:

It timed out, but eventually the file was restored. But I haven't tried for files with > 1000 entries.

@dmaza I am getting an error undeleting some files on beta commons. I think it is related to the number of archived files (entries in filearchive).

Ok. I'll look into it asap. Thanks

Uneducated guess by looking at the stack trace: here it should be dieStatus instead of dieWithError

I can also reproduce the error if I am blocked from a namespace I am trying to delete from (but not if I am sitewide blocked).

Uneducated guess by looking at the stack trace: here it should be dieStatus instead of dieWithError

Yes it is. Thank you

Change 776246 had a related patch set uploaded (by Dmaza; author: Dmaza):

[mediawiki/core@master] UndeletePage: Fix api bad method call

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

Change 776246 merged by jenkins-bot:

[mediawiki/core@master] ApiUndelete: Fix api bad method call

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

Testing coverage:

  • Restoring articles and files of different sizes (see table)
  • Restoring articles which have already been partially restored
    • incl. the two use cases of merge and split edit histories as described here
  • Concurrency
  • Restoring while passing the fileids and timestamp parameters (as described here)
  • Validation
    • Page is a talk page
    • Page does not have a talk page
  • Trying to restored associated talk page while blocked from talk namespace
  • Monitoring exceptions in logstash
  • If subject page undeletion fails (i.e. it doesn't have deleted revisions), talk page undeletion should be aborted

It is difficult to provoke failures on demand, so this is hard to test. In situations where I can provoke failure deleting the content page (e.g. this file, this file or where the content page is not deleted but the associated talk page is) the associated talk page is not deleted.

  • If restoring the associated talk page fails, restoring the subject page should still happen but with a warning about the talk page failing

Again, hard to provoke failures on demand. In situations where I can (e.g. the associated talk page does not exist or is not deleted) the restoring of the content page is successful and I see a warning about the talk page.

Couple of bugs raised during this testing (I don't think any are blockers):

Test environments: Various versions of https://en.wikipedia.beta.wmflabs.org and https://commons.wikimedia.beta.wmflabs.org.