From 9c6d3ab542f61c565bb4f2edd15fd6df190e7d09 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Thu, 3 Dec 2015 18:15:53 -0800 Subject: [PATCH] Generalized exception handling to handle strange errors like captchas. --- rtv/content.py | 6 ++--- rtv/objects.py | 59 ++++++++++++++++++++---------------------------- rtv/subreddit.py | 3 ++- 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/rtv/content.py b/rtv/content.py index 1713fbc..9dd8015 100644 --- a/rtv/content.py +++ b/rtv/content.py @@ -339,7 +339,7 @@ class SubredditContent(Content): try: self.get(0) except IndexError: - raise exceptions.SubredditError('Unable to retrieve subreddit') + raise exceptions.SubredditError('No submissions') @classmethod def from_name(cls, reddit, name, loader, order=None, query=None): @@ -361,7 +361,7 @@ class SubredditContent(Content): if name == 'me': if not reddit.is_oauth_session(): - raise exceptions.AccountError('Could not access user account') + raise exceptions.AccountError('Not logged in') elif order: submissions = reddit.user.get_submitted(sort=order) else: @@ -443,7 +443,7 @@ class SubscriptionContent(Content): try: self.get(0) except IndexError: - raise exceptions.SubscriptionError('Unable to load subscriptions') + raise exceptions.SubscriptionError('No subscriptions') @classmethod def from_user(cls, reddit, loader): diff --git a/rtv/objects.py b/rtv/objects.py index c4b419f..50ac828 100644 --- a/rtv/objects.py +++ b/rtv/objects.py @@ -12,10 +12,10 @@ import threading from contextlib import contextmanager import six -import praw -import requests +from praw.errors import PRAWException +from requests import RequestException -from . import exceptions +from .exceptions import RTVError _logger = logging.getLogger(__name__) @@ -111,25 +111,6 @@ class LoadScreen(object): >>> assert isinstance(terminal.loader.exception, KeyboardInterrupt) """ - HANDLED_EXCEPTIONS = [ - (exceptions.SubscriptionError, 'No Subscriptions'), - (exceptions.AccountError, 'Unable to Access Account'), - (exceptions.SubredditError, 'Invalid Subreddit'), - (praw.errors.InvalidSubreddit, 'Invalid Subreddit'), - (praw.errors.InvalidComment, 'Invalid Comment'), - (praw.errors.InvalidSubmission, 'Invalid Submission'), - (praw.errors.OAuthAppRequired, 'Invalid OAuth data'), - (praw.errors.OAuthException, 'Invalid OAuth data'), - (praw.errors.LoginOrScopeRequired, 'Not Logged In'), - (praw.errors.ClientException, 'Reddit Client Error'), - (praw.errors.NotFound, 'Not Found'), - (praw.errors.APIException, 'Reddit API Error'), - (praw.errors.HTTPException, 'Reddit HTTP Error'), - (requests.HTTPError, 'Unexpected HTTP Error'), - (requests.ConnectionError, 'Connection Error'), - (KeyboardInterrupt, None), - ] - def __init__(self, terminal): self.exception = None @@ -186,19 +167,27 @@ class LoadScreen(object): self._animator.join() self._terminal.stdscr.refresh() - if self.catch_exception and e is not None: - # Log the exception and attach it so the caller can inspect it - self.exception = e - _logger.info('Loader caught: {0} - {1}'.format(type(e).__name__, e)) - # If an error occurred, display a notification on the screen - for base, message in self.HANDLED_EXCEPTIONS: - if isinstance(e, base): - if message: - self._terminal.show_notification(message) - break - else: - return # Re-raise unhandled exceptions - return True # Otherwise swallow the exception and continue + if e is None or not self.catch_exception: + # Skip exception handling + return + + self.exception = e + exc_name = type(e).__name__ + _logger.info('Loader caught: {0} - {1}'.format(exc_name, e)) + + # Some exceptions we want to swallow and display a notification + handled_exceptions = (RTVError, PRAWException, RequestException) + if isinstance(e, handled_exceptions): + # Pass the message straight through to the user + message = six.text_type(e).split('/n') if e else exc_name + self._terminal.show_notification(message) + return True + elif isinstance(e, KeyboardInterrupt): + # Don't need to print anything for this one + return True + else: + # Allow the exception to re-raise + return None def animate(self, delay, interval, message, trail): diff --git a/rtv/subreddit.py b/rtv/subreddit.py index cb95ef3..c82aecd 100644 --- a/rtv/subreddit.py +++ b/rtv/subreddit.py @@ -124,7 +124,8 @@ class SubredditPage(Page): title, content = text.split('\n', 1) with self.term.loader(message='Posting', delay=0): - submission = self.reddit.submit(name, title, text=content) + submission = self.reddit.submit(name, title, text=content, + raise_captcha_exception=True) # Give reddit time to process the submission time.sleep(2.0) if self.term.loader.exception: