From 1afb73b82d410637350005dcfd5a3b81bb8d71ab Mon Sep 17 00:00:00 2001 From: Mathias Kresin Date: Fri, 10 Apr 2015 23:34:07 +0200 Subject: [PATCH] Expose all picoFeed errors to the Frontend when adding a subscription --- controllers/feed.php | 45 ++++++++++++-- jsonrpc.php | 12 +++- locales/ar_AR/translations.php | 7 +++ locales/cs_CZ/translations.php | 7 +++ locales/de_DE/translations.php | 7 +++ locales/es_ES/translations.php | 7 +++ locales/fr_FR/translations.php | 7 +++ locales/it_IT/translations.php | 7 +++ locales/pt_BR/translations.php | 7 +++ locales/sr_RS/translations.php | 7 +++ locales/sr_RS@latin/translations.php | 7 +++ locales/zh_CN/translations.php | 7 +++ models/feed.php | 91 +++++++++++++--------------- 13 files changed, 163 insertions(+), 55 deletions(-) diff --git a/controllers/feed.php b/controllers/feed.php index c182219..dfe3ae0 100644 --- a/controllers/feed.php +++ b/controllers/feed.php @@ -159,17 +159,50 @@ Router\action('subscribe', function() { } $values += array('url' => trim($url), 'download_content' => 0, 'rtl' => 0, 'cloak_referrer' => 0); - $feed_id = Model\Feed\create($values['url'], $values['download_content'], $values['rtl'], $values['cloak_referrer']); - if ($feed_id > 0) { + try { + $feed_id = Model\Feed\create($values['url'], $values['download_content'], $values['rtl'], $values['cloak_referrer']); + } + catch (UnexpectedValueException $e) { + $error_message = t('This subscription already exists.'); + } + catch (PicoFeed\Client\InvalidCertificateException $e) { + $error_message = t('Invalid SSL certificate.'); + } + catch (PicoFeed\Client\InvalidUrlException $e) { + // picoFeed uses this exception for multiple reasons, but doesn't + // provide an exception code to distinguish what exactly happend here + $error_message = $e->getMessage(); + } + catch (PicoFeed\Client\MaxRedirectException $e) { + $error_message = t('Maximum number of HTTP redirections exceeded.'); + } + catch (PicoFeed\Client\MaxSizeException $e) { + $error_message = t('The content size exceeds to maximum allowed size.'); + } + catch (PicoFeed\Client\TimeoutException $e) { + $error_message = t('Connection timeout.'); + } + catch (PicoFeed\Parser\MalformedXmlException $e) { + $error_message = t('Feed is malformed.'); + } + catch (PicoFeed\Reader\SubscriptionNotFoundException $e) { + $error_message = t('Unable to find a subscription.'); + } + catch (PicoFeed\Reader\UnsupportedFeedFormatException $e) { + $error_message = t('Unable to detect the feed format.'); + } + + if (isset($feed_id) && $feed_id !== false) { Session\flash(t('Subscription added successfully.')); Response\redirect('?action=feed-items&feed_id='.$feed_id); } - else if ($feed_id === -2) { - Session\flash_error(t('This subscription already exists.')); - } else { - Session\flash_error(t('Unable to find a subscription.')); + if (! isset($error_message)) { + $error_message = t('Error occured.'); + } + + Session\flash_error($error_message); } Response\html(Template\layout('add', array( diff --git a/jsonrpc.php b/jsonrpc.php index 6a8b988..a25af1b 100644 --- a/jsonrpc.php +++ b/jsonrpc.php @@ -3,6 +3,7 @@ require __DIR__.'/common.php'; use JsonRPC\Server; +use PicoFeed\PicoFeedException; $server = new Server; $server->authentication(array( @@ -24,7 +25,16 @@ $server->register('feed.info', function ($feed_id) { // Add a new feed $server->register('feed.create', function($url) { - $result = Model\Feed\create($url); + try { + $result = Model\Feed\create($url); + } + catch (PicoFeedException $e) { + $result = false; + } + catch (UnexpectedValueException $e) { + $result = false; + } + Model\Config\write_debug(); return $result; diff --git a/locales/ar_AR/translations.php b/locales/ar_AR/translations.php index 5e7b67a..0cf8e2c 100644 --- a/locales/ar_AR/translations.php +++ b/locales/ar_AR/translations.php @@ -231,4 +231,11 @@ return array( 'Original link marks article as read' => 'تحويل العنوان إلى مقروء بمجرد النقر على الرابط الأصلي للعنوان', 'Cloak the image referrer' => 'Cloak the image referrer', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/cs_CZ/translations.php b/locales/cs_CZ/translations.php index 050f272..03d902a 100644 --- a/locales/cs_CZ/translations.php +++ b/locales/cs_CZ/translations.php @@ -231,4 +231,11 @@ return array( 'Original link marks article as read' => 'Původní odkaz označí článek za přečtený', 'Cloak the image referrer' => 'Zamaskovat původce obrázků', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/de_DE/translations.php b/locales/de_DE/translations.php index 1bb7d15..f57c63e 100644 --- a/locales/de_DE/translations.php +++ b/locales/de_DE/translations.php @@ -231,4 +231,11 @@ return array( // 'Original link marks article as read' => '', // 'Cloak the image referrer' => '', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/es_ES/translations.php b/locales/es_ES/translations.php index 1036b23..e285e0b 100644 --- a/locales/es_ES/translations.php +++ b/locales/es_ES/translations.php @@ -231,4 +231,11 @@ return array( 'Original link marks article as read' => 'Link original marca artículo cómo leído', // 'Cloak the image referrer' => '', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/fr_FR/translations.php b/locales/fr_FR/translations.php index 64c960b..326403c 100644 --- a/locales/fr_FR/translations.php +++ b/locales/fr_FR/translations.php @@ -231,4 +231,11 @@ return array( 'Original link marks article as read' => 'Marquer les articles comme lu lors d\'un clic sur le lien original', 'Cloak the image referrer' => 'Falsifier le référent pour les images', 'This subscription already exists.' => 'Cet abonnement existe déjà.', + 'Connection timeout.' => 'Connection timeout.', + 'Error occured.' => 'Error occured.', + 'Feed is malformed.' => 'Feed is malformed.', + 'Invalid SSL certificate.' => 'Invalid SSL certificate.', + 'Maximum number of HTTP redirections exceeded.' => 'Maximum number of HTTP redirections exceeded.', + 'The content size exceeds to maximum allowed size.' => 'The content size exceeds to maximum allowed size.', + 'Unable to detect the feed format.' => 'Unable to detect the feed format.', ); diff --git a/locales/it_IT/translations.php b/locales/it_IT/translations.php index 83be88c..45cf88f 100644 --- a/locales/it_IT/translations.php +++ b/locales/it_IT/translations.php @@ -231,4 +231,11 @@ return array( // 'Original link marks article as read' => '', // 'Cloak the image referrer' => '', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/pt_BR/translations.php b/locales/pt_BR/translations.php index 5f32190..553bd17 100644 --- a/locales/pt_BR/translations.php +++ b/locales/pt_BR/translations.php @@ -231,4 +231,11 @@ return array( // 'Original link marks article as read' => '', // 'Cloak the image referrer' => '', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/sr_RS/translations.php b/locales/sr_RS/translations.php index f5ad1d0..bffcf62 100755 --- a/locales/sr_RS/translations.php +++ b/locales/sr_RS/translations.php @@ -231,4 +231,11 @@ return array( 'Original link marks article as read' => 'Клик на оригиналну везу обележава чланак прочитаним', 'Cloak the image referrer' => 'Прикривај рефератора слика', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/sr_RS@latin/translations.php b/locales/sr_RS@latin/translations.php index 049ea3c..fb2eefe 100755 --- a/locales/sr_RS@latin/translations.php +++ b/locales/sr_RS@latin/translations.php @@ -231,4 +231,11 @@ return array( 'Original link marks article as read' => 'Klik na originalnu vezu obeležava članak pročitanim', 'Cloak the image referrer' => 'Prikrivaj referatora slika', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/locales/zh_CN/translations.php b/locales/zh_CN/translations.php index f759306..daa23d1 100644 --- a/locales/zh_CN/translations.php +++ b/locales/zh_CN/translations.php @@ -231,4 +231,11 @@ return array( // 'Original link marks article as read' => '', // 'Cloak the image referrer' => '', // 'This subscription already exists.' => '', + // 'Connection timeout.' => '', + // 'Error occured.' => '', + // 'Feed is malformed.' => '', + // 'Invalid SSL certificate.' => '', + // 'Maximum number of HTTP redirections exceeded.' => '', + // 'The content size exceeds to maximum allowed size.' => '', + // 'Unable to detect the feed format.' => '', ); diff --git a/models/feed.php b/models/feed.php index a48368f..7d65e7a 100644 --- a/models/feed.php +++ b/models/feed.php @@ -151,60 +151,55 @@ function import_opml($content) // Add a new feed from an URL function create($url, $enable_grabber = false, $force_rtl = false, $cloak_referrer = false) { - try { - $db = Database::get('db'); + $feed_id = false; - // Discover the feed - $reader = new Reader(Config\get_reader_config()); - $resource = $reader->discover($url); + $db = Database::get('db'); - // Feed already there - if ($db->table('feeds')->eq('feed_url', $resource->getUrl())->count()) { - return -2; - } + // Discover the feed + $reader = new Reader(Config\get_reader_config()); + $resource = $reader->discover($url); - // Parse the feed - $parser = $reader->getParser( - $resource->getUrl(), - $resource->getContent(), - $resource->getEncoding() - ); - - if ($enable_grabber) { - $parser->enableContentGrabber(); - } - - $feed = $parser->execute(); - - // Save the feed - $result = $db->table('feeds')->save(array( - 'title' => $feed->getTitle(), - 'site_url' => $feed->getSiteUrl(), - 'feed_url' => $feed->getFeedUrl(), - 'download_content' => $enable_grabber ? 1 : 0, - 'rtl' => $force_rtl ? 1 : 0, - 'last_modified' => $resource->getLastModified(), - 'last_checked' => time(), - 'etag' => $resource->getEtag(), - 'cloak_referrer' => $cloak_referrer ? 1 : 0, - )); - - if ($result) { - - $feed_id = $db->getConnection()->getLastId(); - - Item\update_all($feed_id, $feed->getItems()); - fetch_favicon($feed_id, $feed->getSiteUrl(), $feed->getIcon()); - - Config\write_debug(); - - return (int) $feed_id; - } + // Feed already there + if ($db->table('feeds')->eq('feed_url', $resource->getUrl())->count()) { + throw new \UnexpectedValueException; + } + + // Parse the feed + $parser = $reader->getParser( + $resource->getUrl(), + $resource->getContent(), + $resource->getEncoding() + ); + + if ($enable_grabber) { + $parser->enableContentGrabber(); + } + + $feed = $parser->execute(); + + // Save the feed + $result = $db->table('feeds')->save(array( + 'title' => $feed->getTitle(), + 'site_url' => $feed->getSiteUrl(), + 'feed_url' => $feed->getFeedUrl(), + 'download_content' => $enable_grabber ? 1 : 0, + 'rtl' => $force_rtl ? 1 : 0, + 'last_modified' => $resource->getLastModified(), + 'last_checked' => time(), + 'etag' => $resource->getEtag(), + 'cloak_referrer' => $cloak_referrer ? 1 : 0, + )); + + if ($result) { + $feed_id = $db->getConnection()->getLastId(); + + Item\update_all($feed_id, $feed->getItems()); + fetch_favicon($feed_id, $feed->getSiteUrl(), $feed->getIcon()); } - catch (PicoFeedException $e) {} Config\write_debug(); - return -1; + + return $feed_id; } // Refresh all feeds