diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index 239e143e2..86f29a525 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -157,7 +157,8 @@ class SpotifyPlugin(MetadataSourcePlugin, BeetsPlugin): with open(self.tokenfile, 'w') as f: json.dump({'access_token': self.access_token}, f) - def _handle_response(self, request_type, url, params=None): + def _handle_response(self, request_type, url, params=None, retry_count=0, + max_retries=3): """Send a request, reauthenticating if necessary. :param request_type: Type of :class:`Request` constructor, @@ -195,12 +196,17 @@ class SpotifyPlugin(MetadataSourcePlugin, BeetsPlugin): raise SpotifyAPIError(f'API Error: {e.response.status_code}\n' f'URL: {url}\nparams: {params}') elif e.response.status_code == 429: - seconds = response.headers.get('Retry-After', - DEFAULT_WAITING_TIME) - self._log.debug(f'Too many API requests. Retrying after ' - f'{seconds} seconds.') - time.sleep(int(seconds) + 1) - return self._handle_response(request_type, url, params=params) + if retry_count < max_retries: + seconds = response.headers.get('Retry-After', + DEFAULT_WAITING_TIME) + self._log.debug(f'Too many API requests. Retrying after ' + f'{seconds} seconds.') + time.sleep(int(seconds) + 1) + return self._handle_response(request_type, url, + params=params, + retry_count=retry_count + 1) + else: + raise SpotifyAPIError('Maximum retries reached.') elif e.response.status_code == 503: self._log.error('Service Unavailable.') raise SpotifyAPIError('Service Unavailable.') diff --git a/docs/changelog.rst b/docs/changelog.rst index 0e1d8611e..da30420c1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -142,6 +142,7 @@ New features: Bug fixes: +* Fix retry-logic for Spotify plugin. * Fix a crash when the Spotify API timeouts or does not return a `Retry-After` interval. :bug:`4942` * :doc:`/plugins/scrub`: Fixed the import behavior where scrubbed database tags