Merge "Make WikiPage::doDeleteArticle more robust"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 29 Aug 2016 23:28:12 +0000 (23:28 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 29 Aug 2016 23:28:12 +0000 (23:28 +0000)
docs/hooks.txt
includes/page/WikiPage.php

index 1e3cf1e..a7fb873 100644 (file)
@@ -596,7 +596,7 @@ $outputPage: OutputPage that can be used to append the output.
 &$user: the user that deleted the article
 $reason: the reason the article was deleted
 $id: id of the article that was deleted
-$content: the Content of the deleted page
+$content: the Content of the deleted page (or null, when deleting a broken page)
 $logEntry: the ManualLogEntry used to record the deletion
 $archivedRevisionCount: the number of revisions archived during the deletion
 
@@ -3732,7 +3732,8 @@ a page is deleted. Called in WikiPage::getDeletionUpdates(). Note that updates
 specific to a content model should be provided by the respective Content's
 getDeletionUpdates() method.
 $page: the WikiPage
-$content: the Content to generate updates for
+$content: the Content to generate updates for (or null, if the Content could not be loaded
+due to an error)
 &$updates: the array of DataUpdate objects. Hook function may want to add to it.
 
 'XmlDumpWriterOpenPage': Called at the end of XmlDumpWriter::openPage, to allow
index 4066501..e1d9f99 100644 (file)
@@ -2883,7 +2883,14 @@ class WikiPage implements Page, IDBAccessObject {
                // unless they actually try to catch exceptions (which is rare).
 
                // we need to remember the old content so we can use it to generate all deletion updates.
-               $content = $this->getContent( Revision::RAW );
+               try {
+                       $content = $this->getContent( Revision::RAW );
+               } catch ( Exception $ex ) {
+                       wfLogWarning( __METHOD__ . ': failed to load content during deletion! '
+                               . $ex->getMessage() );
+
+                       $content = null;
+               }
 
                // Bitfields to further suppress the content
                if ( $suppress ) {
@@ -3024,8 +3031,16 @@ class WikiPage implements Page, IDBAccessObject {
         *   may already return null when the page proper was deleted.
         */
        public function doDeleteUpdates( $id, Content $content = null ) {
+               try {
+                       $countable = $this->isCountable();
+               } catch ( Exception $ex ) {
+                       // fallback for deleting broken pages for which we cannot load the content for
+                       // some reason. Note that doDeleteArticleReal() already logged this problem.
+                       $countable = false;
+               }
+
                // Update site status
-               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) );
+               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$countable, -1 ) );
 
                // Delete pagelinks, update secondary indexes, etc
                $updates = $this->getDeletionUpdates( $content );
@@ -3641,7 +3656,14 @@ class WikiPage implements Page, IDBAccessObject {
                if ( !$content ) {
                        // load content object, which may be used to determine the necessary updates.
                        // XXX: the content may not be needed to determine the updates.
-                       $content = $this->getContent( Revision::RAW );
+                       try {
+                               $content = $this->getContent( Revision::RAW );
+                       } catch ( Exception $ex ) {
+                               // If we can't load the content, something is wrong. Perhaps that's why
+                               // the user is trying to delete the page, so let's not fail in that case.
+                               // Note that doDeleteArticleReal() will already have logged an issue with
+                               // loading the content.
+                       }
                }
 
                if ( !$content ) {