Sfoglia il codice sorgente

Fix muting of feeds gone with HTTP 410 (#9391)

* Fix muting of feeds gone with HTTP 410

A feed answering HTTP 410 Gone is meant to be muted (#3561), but:

* Since #6037, FreshRSS_Feed_Exception extends Minz_Exception, which
  resets any code other than its own error levels to 0, so the check for
  410 never matched. FreshRSS_Feed_Exception now keeps the HTTP status
  code it is given.
* FreshRSS_FeedDAO::mute() mutes by negating the TTL, which leaves a feed
  with the default TTL (0) unmuted. Mute the feed the way the feed
  settings and dynamic OPML categories do instead.

* A bit of cleaning

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Nikolai Shcheglov 1 giorno fa
parent
commit
a93bd27b7d

+ 2 - 2
app/Controllers/feedController.php

@@ -606,8 +606,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 				if ($e->getCode() === 410) {
 					// HTTP 410 Gone
 					Minz_Log::warning('Muting gone feed: ' . $feed->url(false));
-					$feedDAO->mute($feed->id(), true);
-					$feed->_ttl(-abs($feed->ttl())); // Replicate behavior of line above which acts directly into the DB
+					$feed->_mute(true);
+					$feedDAO->updateFeed($feed->id(), ['ttl' => $feed->ttl(raw: true)]);	// Also when the feed has the default TTL (0)
 				}
 				$feed->unlock();
 				continue;

+ 7 - 0
app/Exceptions/FeedException.php

@@ -3,4 +3,11 @@ declare(strict_types=1);
 
 class FreshRSS_Feed_Exception extends Minz_Exception {
 
+	/**
+	 * @param int $code The HTTP status code when known, e.g. 410 Gone, which mutes the feed
+	 */
+	public function __construct(string $message = '', int $code = 0, ?Throwable $previous = null) {
+		parent::__construct($message, previous: $previous);
+		$this->code = $code;	// Minz_Exception would reset it, keeping only its own error levels
+	}
 }

+ 0 - 18
app/Models/FeedDAO.php

@@ -261,24 +261,6 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
 		}
 	}
 
-	public function mute(int $id, bool $value = true): int|false {
-		$sign = $value ? '-' : '';
-		$sql = <<<SQL
-			UPDATE `_feed`
-			SET ttl = {$sign}ABS(ttl)
-			WHERE id = :id
-			SQL;
-		$stm = $this->pdo->prepare($sql);
-		if ($stm !== false &&
-			$stm->bindValue(':id', $id, PDO::PARAM_INT) &&
-			$stm->execute()) {
-			return $stm->rowCount();
-		}
-		$info = $stm === false ? $this->pdo->errorInfo() : $stm->errorInfo();
-		Minz_Log::error('SQL error ' . __METHOD__ . json_encode($info));
-		return false;
-	}
-
 	public function changeCategory(int $idOldCat, int $idNewCat): int|false {
 		$catDAO = FreshRSS_Factory::createCategoryDao();
 		$newCat = $catDAO->searchById($idNewCat);

+ 14 - 0
tests/app/Exceptions/FeedExceptionTest.php

@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+final class FeedExceptionTest extends \PHPUnit\Framework\TestCase {
+
+	public function test_keepsHttpStatusCode(): void {
+		$previous = new RuntimeException('previous');
+		$e = new FreshRSS_Feed_Exception('Gone', 410, $previous);
+		self::assertSame(410, $e->getCode());	// feedController mutes a feed on HTTP 410 Gone
+		self::assertSame('Gone', $e->getMessage());
+		self::assertSame($previous, $e->getPrevious());
+		self::assertSame(0, (new FreshRSS_Feed_Exception())->getCode());
+	}
+}