Skip to content

spotify: Handle API failures - #5910

Closed
9999years wants to merge 1 commit into
beetbox:masterfrom
9999years:spotify-apierror
Closed

spotify: Handle API failures#5910
9999years wants to merge 1 commit into
beetbox:masterfrom
9999years:spotify-apierror

Conversation

@9999years

Copy link
Copy Markdown
Contributor

Lots of these weren't handled, leading to crashes while importing.

To Do

  • Documentation. (If you've added a new command-line flag, for example, find the appropriate page under docs/ to describe it.)
  • Changelog. (Add an entry to docs/changelog.rst to the bottom of one of the lists near the top of the document.)
  • Tests. (Very much encouraged but not strictly required.)

Copilot AI review requested due to automatic review settings July 31, 2025 23:51
@github-actions

Copy link
Copy Markdown

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves error handling in the Spotify plugin by adding proper exception handling around API calls that previously could crash during imports. The changes wrap critical Spotify API interactions with try-catch blocks to gracefully handle API failures.

Key changes:

  • Added exception handling for API failures in album and track retrieval methods
  • Modified track_info method to return None on API errors instead of crashing
  • Updated type annotations to reflect the new nullable return types

Comment thread beetsplug/spotify.py Outdated
Comment thread beetsplug/spotify.py
def track_info(self, track_id: str):
def track_info(
self, track_id: str
) -> Tuple[Any | None, Any | None, Any | None, Any | None] | None:

Copilot AI Jul 31, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The return type annotation is verbose and unclear. Consider creating a type alias or using a more descriptive approach, such as TrackInfoTuple | None where TrackInfoTuple = Tuple[Optional[Any], Optional[Any], Optional[Any], Optional[Any]].

Suggested change
) -> Tuple[Any | None, Any | None, Any | None, Any | None] | None:
) -> TrackInfoTuple | None:

Copilot uses AI. Check for mistakes.
@codecov

codecov Bot commented Jul 31, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 18.51852% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.67%. Comparing base (5beb3d1) to head (55b3e45).

Files with missing lines Patch % Lines
beetsplug/spotify.py 18.51% 21 Missing and 1 partial ⚠️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread beetsplug/spotify.py
Comment on lines +296 to +302
try:
album_data = self._handle_response(
"get", self.album_url + spotify_id
)
except APIError:
return None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach introduces a lot of duplication in the code. I think a cleaner approach would be to never raise APIError in the first place.

See _handle_response method - I'd suggest removing all lines that raise APIError and returning None instead.

@semohr

semohr commented Aug 2, 2025

Copy link
Copy Markdown
Contributor

Maybe it is worth taking a step back here:

How do we want to handle errors in metadata plugins in general? E.g. what should happen if one plugin fails because a remote service is currently unreachable? Do we want beets to crash here or just warn a user?

I think raising errors in the specific metadata plugin (such as spotify or deezer) is completely fine. We should handle errors globally for any metadata plugins tho and warn users.

Proposal: Let's add error handling to the metadata_plugins.py file and warn the user that some plugin(s) did not complete a lookup or function call successfully. This would also move responsibilities away from the plugin developers and reduce unnecessary & duplicate error handling.

@semohr

semohr commented Aug 22, 2025

Copy link
Copy Markdown
Contributor

@9999years Are you planning to keep looking into the metadataplugin layer for adding error handling? If you want to take the lead on it, go ahead. I’d be glad to chime in or help out later, since it’s also needed for the aisauce plugin. From what I can tell it shouldn’t be too difficult to add.

@9999years

Copy link
Copy Markdown
Contributor Author

@semohr Feel free, I might get back to this in the future but I'm not sure when.

@snejus
snejus requested a review from a team as a code owner October 14, 2025 22:30
Lots of these weren't handled, leading to crashes while importing.
@JOJ0 JOJ0 added plugin Pull requests that are plugins related spotify spotify plugin metadata_plugins An issue that is generally related to metadata plugin logic. core Pull requests that modify the beets core `beets` and removed metadata_plugins An issue that is generally related to metadata plugin logic. labels Jan 10, 2026
@snejus
snejus marked this pull request as draft January 15, 2026 02:46
snejus added a commit that referenced this pull request Jan 31, 2026
When a metadata plugin raises an exception during the auto-tagger
process, the entire operation crashes. This behavior is not desirable,
since metadata lookups can legitimately fail for various reasons (e.g.,
temporary API downtime, network issues, or offline usage).

This PR introduces a safeguard by adding general exception handling
around metadata plugin calls. Instead of causing the whole process to
fail, exceptions from individual plugins are now caught and logged. This
ensures that the auto-tagger continues to function with the remaining
available metadata sources. I used a proxy pattern here as this
seems like an elegant solution to me.

This replaces the efforts from #5910
@9999years 9999years closed this Feb 12, 2026
@9999years
9999years deleted the spotify-apierror branch March 30, 2026 18:14
@snejus snejus removed the plugin Pull requests that are plugins related label Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Pull requests that modify the beets core `beets` spotify spotify plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants