From f91600a0c418b06f1ec2ef3173a7249ec1b1bfce Mon Sep 17 00:00:00 2001 From: Rafael Moraes <50295204+glomatico@users.noreply.github.com> Date: Tue, 24 Feb 2026 15:54:36 -0300 Subject: [PATCH] Standardize media exceptions and update handlers --- votify/interface/audio.py | 1 - votify/interface/episode.py | 10 +++++-- votify/interface/exceptions.py | 52 ++++++++++++++++++++++------------ votify/interface/song.py | 17 +++++++---- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/votify/interface/audio.py b/votify/interface/audio.py index 7315744..66eb2de 100644 --- a/votify/interface/audio.py +++ b/votify/interface/audio.py @@ -31,7 +31,6 @@ class SpotifyAudioInterface(SpotifyBaseInterface): ): raise VotifyMediaAudioQualityNotAvailableException( media_id=playback_info["metadata"]["uri"].split(":")[-1], - playback_info=playback_info, ) file_id = None diff --git a/votify/interface/episode.py b/votify/interface/episode.py index 9d9ce48..c6795ba 100644 --- a/votify/interface/episode.py +++ b/votify/interface/episode.py @@ -3,7 +3,8 @@ import logging from .audio import SpotifyAudioInterface from .constants import COVER_SIZE_ID_MAP_EPISODE, DEFAULT_EPISODE_DECRYPTION_KEY from .enums import MediaType -from .types import MediaTags, SpotifyMedia, DecryptionKey, DecryptionKeyAv +from .exceptions import VotifyMediaAudioQualityNotAvailableException +from .types import DecryptionKey, DecryptionKeyAv, MediaTags, SpotifyMedia logger = logging.getLogger(__name__) @@ -47,7 +48,12 @@ class SpotifyEpisodeInterface(SpotifyAudioInterface): episode_data["coverArt"]["sources"][0]["url"] ) - media.stream_info = await self.get_stream_info(playback_info, True) + try: + media.stream_info = await self.get_stream_info(playback_info, True) + except VotifyMediaAudioQualityNotAvailableException as e: + e.media_metadata = episode_data + raise + media.decryption_key = DecryptionKeyAv( DecryptionKey( decryption_key=DEFAULT_EPISODE_DECRYPTION_KEY, diff --git a/votify/interface/exceptions.py b/votify/interface/exceptions.py index 75d5550..806add8 100644 --- a/votify/interface/exceptions.py +++ b/votify/interface/exceptions.py @@ -15,33 +15,49 @@ class VotifyUnsupportedMediaTypeException(VotiyException): self.media_type = media_type -class VotifyDrmDisabledException(VotiyException): - def __init__(self, media_id: str, media_metadata: dict | None = None): - super().__init__(f"DRM is disabled, cannot process media: {media_id}") +class VotifyMediaException(VotiyException): + def __init__(self, message: str, media_id: str, media_metadata: dict | None = None): + super().__init__(f"{message}: {media_id}") self.media_id = media_id self.media_metadata = media_metadata -class VotifyMediaNotFoundException(VotiyException): +class VotifyDrmDisabledException(VotifyMediaException): def __init__(self, media_id: str, media_metadata: dict | None = None): - super().__init__(f"Media not found: {media_id}") - - self.media_id = media_id - self.media_metadata = media_metadata + super().__init__( + "DRM is disabled, cannot process media", + media_id=media_id, + media_metadata=media_metadata, + ) -class VotifyMediaUnstreamableException(VotiyException): +class VotifyMediaNotFoundException(VotifyMediaException): def __init__(self, media_id: str, media_metadata: dict | None = None): - super().__init__(f"Media is not streamable: {media_id}") - - self.media_id = media_id - self.media_metadata = media_metadata + super().__init__( + "Media not found", + media_id=media_id, + media_metadata=media_metadata, + ) -class VotifyMediaAudioQualityNotAvailableException(VotiyException): - def __init__(self, media_id: str, playback_info: dict | None = None): - super().__init__(f"Selected audio quality is not available: {media_id}") +class VotifyMediaUnstreamableException(VotifyMediaException): + def __init__(self, media_id: str, media_metadata: dict | None = None): + super().__init__( + "Media is not streamable", + media_id=media_id, + media_metadata=media_metadata, + ) - self.media_id = media_id - self.playback_info = playback_info + +class VotifyMediaAudioQualityNotAvailableException(VotifyMediaException): + def __init__( + self, + media_id: str, + media_metadata: dict | None = None, + ): + super().__init__( + "Selected audio quality is not available", + media_id=media_id, + media_metadata=media_metadata, + ) diff --git a/votify/interface/song.py b/votify/interface/song.py index a890d82..8ee0ab6 100644 --- a/votify/interface/song.py +++ b/votify/interface/song.py @@ -6,6 +6,9 @@ from ..api import VotifyRequestException from .audio import SpotifyAudioInterface from .constants import COVER_SIZE_ID_MAP_SONG from .enums import MediaType +from .exceptions import ( + VotifyMediaAudioQualityNotAvailableException, +) from .types import MediaLyrics, MediaTags, SpotifyMedia logger = logging.getLogger(__name__) @@ -57,11 +60,15 @@ class SpotifySongInterface(SpotifyAudioInterface): media.album_metadata["coverArt"]["sources"][0]["url"] ) - media.stream_info = await self.get_stream_info(playback_info, False) - if media.stream_info is not None: - media.decryption_key = await self.get_widevine_decryption_key( - media.stream_info.audio_track.widevine_pssh - ) + try: + media.stream_info = await self.get_stream_info(playback_info, False) + except VotifyMediaAudioQualityNotAvailableException as e: + e.media_metadata = track_data + raise + + media.decryption_key = await self.get_widevine_decryption_key( + media.stream_info.audio_track.widevine_pssh + ) logger.debug(f"Processed song media: {media}")