From ccfda079c813f786423ce4163e638bc2dd05bdfe Mon Sep 17 00:00:00 2001 From: Loisaida Sam Date: Thu, 2 Apr 2020 15:03:24 -0400 Subject: [PATCH] Propagate refresh token error, fixes #259 (#261) * Propagate refresh token error #259 https://github.com/plamere/spotipy/issues/259 * Lint * Format Co-authored-by: Stephane Bruckert --- CHANGELOG.md | 3 ++- spotipy/__init__.py | 1 + spotipy/client.py | 19 +------------------ spotipy/exceptions.py | 15 +++++++++++++++ spotipy/oauth2.py | 20 +++++++++++--------- tests/integration/test_user_endpoints.py | 2 +- 6 files changed, 31 insertions(+), 29 deletions(-) create mode 100644 spotipy/exceptions.py diff --git a/CHANGELOG.md b/CHANGELOG.md index d9453b9..ffbcd77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Close session when Spotipy object is unloaded + - Propagate refresh token error ## [2.10.0] - 2020-03-18 @@ -46,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2.8.0] - 2020-02-12 -### Added +### Added - Support for `playlist_cover_image` - Support `after` and `before` parameter in `current_user_recently_played` diff --git a/spotipy/__init__.py b/spotipy/__init__.py index dd9eb13..8681052 100644 --- a/spotipy/__init__.py +++ b/spotipy/__init__.py @@ -1,3 +1,4 @@ from .client import * # noqa from .oauth2 import * # noqa from .util import * # noqa +from .exceptions import * # noqa diff --git a/spotipy/client.py b/spotipy/client.py index d6d12d5..cb3cca6 100644 --- a/spotipy/client.py +++ b/spotipy/client.py @@ -4,8 +4,6 @@ from __future__ import print_function -__all__ = ["Spotify", "SpotifyException"] - import json import sys import warnings @@ -14,22 +12,7 @@ import requests import urllib3 import six - -class SpotifyException(Exception): - def __init__(self, http_status, code, msg, headers=None): - self.http_status = http_status - self.code = code - self.msg = msg - # `headers` is used to support `Retry-After` in the event of a - # 429 status code. - if headers is None: - headers = {} - self.headers = headers - - def __str__(self): - return "http status: {0}, code:{1} - {2}".format( - self.http_status, self.code, self.msg - ) +from spotipy.exceptions import SpotifyException class Spotify(object): diff --git a/spotipy/exceptions.py b/spotipy/exceptions.py new file mode 100644 index 0000000..5c979a5 --- /dev/null +++ b/spotipy/exceptions.py @@ -0,0 +1,15 @@ +class SpotifyException(Exception): + + def __init__(self, http_status, code, msg, headers=None): + self.http_status = http_status + self.code = code + self.msg = msg + # `headers` is used to support `Retry-After` in the event of a + # 429 status code. + if headers is None: + headers = {} + self.headers = headers + + def __str__(self): + return 'http status: {0}, code:{1} - {2}'.format( + self.http_status, self.code, self.msg) diff --git a/spotipy/oauth2.py b/spotipy/oauth2.py index 6271a72..3471180 100644 --- a/spotipy/oauth2.py +++ b/spotipy/oauth2.py @@ -18,6 +18,7 @@ import warnings import requests from spotipy.util import CLIENT_CREDS_ENV_VARS, get_host_port +from spotipy.exceptions import SpotifyException # Workaround to support both python 2 & 3 import six @@ -273,7 +274,6 @@ class SpotifyOAuth(SpotifyAuthBase): f.close() except IOError: self._warn("couldn't write token cache to " + self.cache_path) - pass def _is_scope_subset(self, needle_scope, haystack_scope): needle_scope = set(needle_scope.split()) if needle_scope else set() @@ -461,15 +461,17 @@ class SpotifyOAuth(SpotifyAuthBase): proxies=self.proxies, timeout=self.requests_timeout, ) - if response.status_code != 200: - if False: # debugging code - print("headers", headers) - print("request", response.url) - self._warn( - "couldn't refresh token: code:%d reason:%s" - % (response.status_code, response.reason) + try: + response.raise_for_status() + except BaseException: + message = "Couldn't refresh token: code:%d reason:%s" % ( + response.status_code, + response.reason, ) - return None + raise SpotifyException(response.status_code, + -1, + message, + headers) token_info = response.json() token_info = self._add_custom_values_to_token_info(token_info) if "refresh_token" not in token_info: diff --git a/tests/integration/test_user_endpoints.py b/tests/integration/test_user_endpoints.py index adf0d6d..1e0163f 100644 --- a/tests/integration/test_user_endpoints.py +++ b/tests/integration/test_user_endpoints.py @@ -283,7 +283,7 @@ class SpotipyBrowseApiTests(unittest.TestCase): cat_id = cat['id'] if cat_id == category: response = self.spotify.category_playlists(category_id=cat_id) - self.assertGreater(len(response['playlists']["items"]), 0) + self.assertGreater(len(response['playlists']["items"]), 0) def test_new_releases(self): response = self.spotify.new_releases()