diff --git a/src/spotifyaio/__init__.py b/src/spotifyaio/__init__.py index 3d96c087..c64c2a62 100644 --- a/src/spotifyaio/__init__.py +++ b/src/spotifyaio/__init__.py @@ -4,6 +4,7 @@ SpotifyAuthenticationFailedError, SpotifyConnectionError, SpotifyError, + SpotifyNotFoundError, ) from .models import ( Album, @@ -66,6 +67,7 @@ "SpotifyClient", "SpotifyConnectionError", "SpotifyError", + "SpotifyNotFoundError", "Track", "UserProfile", ] diff --git a/src/spotifyaio/exceptions.py b/src/spotifyaio/exceptions.py index 61f86cef..676b9e75 100644 --- a/src/spotifyaio/exceptions.py +++ b/src/spotifyaio/exceptions.py @@ -11,3 +11,7 @@ class SpotifyConnectionError(SpotifyError): class SpotifyAuthenticationFailedError(SpotifyError): """Spotify authentication failed exception.""" + + +class SpotifyNotFoundError(SpotifyError): + """Spotify not found exception.""" diff --git a/src/spotifyaio/spotify.py b/src/spotifyaio/spotify.py index 8c9ea189..6039418e 100644 --- a/src/spotifyaio/spotify.py +++ b/src/spotifyaio/spotify.py @@ -12,7 +12,7 @@ import orjson from yarl import URL -from spotifyaio.exceptions import SpotifyConnectionError +from spotifyaio.exceptions import SpotifyConnectionError, SpotifyNotFoundError from spotifyaio.models import ( Album, AlbumsResponse, @@ -126,7 +126,13 @@ async def _request( if response.status == 204: return "" - return await response.text() + text = await response.text() + + if '"status": 404' in text: + msg = f"Resource not found: {uri}" + raise SpotifyNotFoundError(msg) + + return text async def _get(self, uri: str, params: dict[str, Any] | None = None) -> str: """Handle a GET request to Spotify.""" diff --git a/tests/fixtures/playlist_not_found.json b/tests/fixtures/playlist_not_found.json new file mode 100644 index 00000000..94872d3f --- /dev/null +++ b/tests/fixtures/playlist_not_found.json @@ -0,0 +1,6 @@ +{ + "error": { + "status": 404, + "message": "Resource not found" + } +} diff --git a/tests/test_spotify.py b/tests/test_spotify.py index e6e4331a..9b37780c 100644 --- a/tests/test_spotify.py +++ b/tests/test_spotify.py @@ -11,7 +11,12 @@ import pytest from yarl import URL -from spotifyaio import RepeatMode, SpotifyClient, SpotifyConnectionError +from spotifyaio import ( + RepeatMode, + SpotifyClient, + SpotifyConnectionError, + SpotifyNotFoundError, +) from . import load_fixture from .const import HEADERS, SPOTIFY_URL @@ -862,6 +867,23 @@ async def test_get_playlist( ) +async def test_get_not_found_playlist( + responses: aioresponses, + authenticated_client: SpotifyClient, +) -> None: + """Test retrieving not found playlist.""" + responses.get( + f"{SPOTIFY_URL}/v1/playlists/37i9dQZF1DXcBWIGoYBM5M?additional_types=track,episode", + status=200, + body=load_fixture("playlist_not_found.json"), + ) + with pytest.raises( + SpotifyNotFoundError, + match="Resource not found: v1/playlists/37i9dQZF1DXcBWIGoYBM5M", + ): + await authenticated_client.get_playlist("37i9dQZF1DXcBWIGoYBM5M") + + @pytest.mark.parametrize( "fixture", [