From 2fdc433cb3ed6fa09d0b3f18fdbc8e590a76cfbb Mon Sep 17 00:00:00 2001 From: James Lu Date: Sun, 14 Oct 2018 12:38:10 -0700 Subject: [PATCH] RSS: show soft errors set by feedparser when no entries are found Hopefully this will ease debugging - e.g. a bad TLS certificate will now show "Error: Couldn't get RSS feed. Parser error: " instead of only a generic message. --- plugins/RSS/plugin.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/RSS/plugin.py b/plugins/RSS/plugin.py index feb19cb59..a79442654 100644 --- a/plugins/RSS/plugin.py +++ b/plugins/RSS/plugin.py @@ -92,7 +92,7 @@ class InvalidFeedUrl(ValueError): class Feed: __slots__ = ('url', 'name', 'data', 'last_update', 'entries', 'etag', 'modified', 'initial', - 'lock', 'announced_entries') + 'lock', 'announced_entries', 'last_exception') def __init__(self, name, url, initial, plugin_is_loading=False, announced=None): assert name, name @@ -113,6 +113,7 @@ class Feed: self.lock = threading.Lock() self.announced_entries = announced or \ utils.structures.TruncatableSet() + self.last_exception = None def __repr__(self): return 'Feed(%r, %r, %b, , %r)' % \ @@ -328,6 +329,16 @@ class RSS(callbacks.Plugin): feed.data = d.feed feed.entries = d.entries feed.last_update = time.time() + # feedparser will store soft errors in bozo_exception and set + # the "bozo" bit to 1 on supported platforms: + # https://pythonhosted.org/feedparser/bozo.html + # If this error caused us to e.g. not get any entries at all, + # it may be helpful to show it as well. + if getattr(d, 'bozo', 0) and hasattr(d, 'bozo_exception'): + feed.last_exception = d.bozo_exception + else: + feed.last_exception = None + (initial, feed.initial) = (feed.initial, False) self.announce_feed(feed, initial) @@ -555,7 +566,12 @@ class RSS(callbacks.Plugin): self.update_feed_if_needed(feed) entries = feed.entries if not entries: - irc.error(_('Couldn\'t get RSS feed.')) + s = _('Couldn\'t get RSS feed.') + # If we got a soft parsing exception on our last run, show the error. + if feed.last_exception is not None: + s += _(' Parser error: ') + s += str(feed.last_exception) + irc.error(s) return n = n or self.registryValue('defaultNumberOfHeadlines', channel) entries = list(filter(lambda e:self.should_send_entry(channel, e),