From 67cc4545952b7cae960a08c7bb71058f9d39be91 Mon Sep 17 00:00:00 2001 From: Sonny Bakker Date: Sat, 18 Sep 2021 21:20:45 +0200 Subject: [PATCH] Update twitter error handling --- .../collection/tests/twitter/client/tests.py | 32 +++++++++++++ src/newsreader/news/collection/twitter.py | 48 ++++++++++--------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/newsreader/news/collection/tests/twitter/client/tests.py b/src/newsreader/news/collection/tests/twitter/client/tests.py index 9730d92..5db9f35 100644 --- a/src/newsreader/news/collection/tests/twitter/client/tests.py +++ b/src/newsreader/news/collection/tests/twitter/client/tests.py @@ -193,3 +193,35 @@ class TwitterClientTestCase(TestCase): self.assertIsNone(user.twitter_oauth_token) self.assertIsNone(user.twitter_oauth_token_secret) + + def test_client_does_not_reset_token(self): + """ + The user's token and refresh token should not be reset when an generic + exception is caught + """ + user = UserFactory( + twitter_oauth_token=str(uuid4()), twitter_oauth_token_secret=str(uuid4()) + ) + timeline = TwitterTimelineFactory(user=user) + + response = Mock(json=lambda: {"errors": [{"code": 100}]}) + + self.mocked_read.side_effect = StreamException( + message="Generic message", response=response + ) + + with TwitterClient([timeline]) as client: + for data, stream in client: + with self.subTest(data=data, stream=stream): + self.assertIsNone(data) + self.assertIsNone(stream) + self.assertEquals(stream.rule.error, "") + self.assertEquals(stream.rule.succeeded, False) + + self.mocked_read.assert_called() + + user.refresh_from_db() + timeline.refresh_from_db() + + self.assertIsNotNone(user.twitter_oauth_token) + self.assertIsNotNone(user.twitter_oauth_token_secret) diff --git a/src/newsreader/news/collection/twitter.py b/src/newsreader/news/collection/twitter.py index 2004fa1..5d5a773 100644 --- a/src/newsreader/news/collection/twitter.py +++ b/src/newsreader/news/collection/twitter.py @@ -250,39 +250,41 @@ class TwitterClient(PostClient): try: response_data = e.response.json() except JSONDecodeError: + logger.exception("Could not parse json for request") continue if "errors" in response_data: errors = response_data["errors"] token_expired = any(error["code"] == 89 for error in errors) - try: - import sentry_sdk + if token_expired: + try: + import sentry_sdk - with sentry_sdk.push_scope() as scope: - scope.set_extra("content", response_data) - sentry_sdk.capture_message( - "Twitter authentication credentials reset" - ) - except ImportError: - pass + with sentry_sdk.push_scope() as scope: + scope.set_extra("content", response_data) + sentry_sdk.capture_message( + "Twitter authentication credentials reset" + ) + except ImportError: + pass - stream.rule.user.twitter_oauth_token = None - stream.rule.user.twitter_oauth_token_secret = None - stream.rule.user.save() + stream.rule.user.twitter_oauth_token = None + stream.rule.user.twitter_oauth_token_secret = None + stream.rule.user.save() - message = _( - "Your Twitter account credentials have expired. Re-authenticate in" - " the settings page to keep retrieving Twitter specific information" - " from your account." - ) + message = _( + "Your Twitter account credentials have expired. Re-authenticate in" + " the settings page to keep retrieving Twitter specific information" + " from your account." + ) - send_mail( - "Twitter account needs re-authentication", - message, - None, - [stream.rule.user.email], - ) + send_mail( + "Twitter account needs re-authentication", + message, + None, + [stream.rule.user.email], + ) continue finally: