[Mobile] Fix offline album track downloads after v1 SDK migration#14275
Merged
dylanjeffers merged 1 commit intomainfrom May 7, 2026
Merged
[Mobile] Fix offline album track downloads after v1 SDK migration#14275dylanjeffers merged 1 commit intomainfrom
dylanjeffers merged 1 commit intomainfrom
Conversation
Track downloads inside an album/collection were failing with a generic error icon since the v1 SDK migration. Two issues in downloadTrackWorker.ts compounded: 1. downloadTrackAudio() built the stream URL via getTrackStreamUrl(), ignoring track.stream.url. The v1 API returns a pre-signed stream URL (with mirrors) on the track itself; AudioPlayer prefers it for online streaming and only falls back to manual URL construction when stream.url is missing. The offline worker skipped that working path, so it relied on the fallback for every track. 2. downloadTrackCoverArt() throws when no artwork URI returns 200. Because cover art runs in `all([cover, audio, json])`, a single flaky artwork host fails the entire track download — even though audio is the only essential payload. The collection cover art download follows the opposite (best-effort) pattern. Fix both: prefer track.stream.url with mirror fallback (matches the AudioPlayer logic), keep the manual URL construction as a last resort, and make cover art best-effort. Also log the underlying error instead of swallowing it silently in the catch block, so future regressions are diagnosable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Track downloads were failing in offline mode — the user-visible symptom is "clicks download, sees a track attempt, then a failure icon." This affects both individual track downloads (favoriting a track with auto-download on, or any other path that queues a single track) and tracks inside an album/collection download, because every track-job entry point lands in the same queue and is processed by the same worker.
Two compounding issues in
downloadTrackWorker.ts, both effectively introduced by the v1 SDK migration (#13728):downloadTrackAudioskipped the v1 pre-signed stream URL. It built the URL viasdk.tracks.getTrackStreamUrl(), ignoringtrack.stream.url. The v1 API returns a pre-signed stream URL (with mirrors) on the track itself;AudioPlayerprefers it for online streaming and only falls back to manual URL construction whenstream.urlis missing. The offline worker skipped that working path entirely, so it relied on the fallback for every track.downloadTrackCoverArtwas fatal. It threw when no artwork URI returned 200, and because cover art runs inall([cover, audio, json]), a single flaky artwork host failed the entire track download — even though audio is the only essential payload. The collection cover art download follows the opposite (best-effort) pattern; this PR brings the track version in line.Plus
downloadTrackAsync'scatchblock silently swallowed the error — no logs, no Sentry breadcrumb. That's why this had been hard to diagnose.Why this fixes both individual tracks and collections
Every track-job source —
requestDownloadCollectionSaga,requestDownloadFavoritedCollectionSaga,requestDownloadAllFavoritesSaga,watchSaveTrackSaga(standalone track favorite),watchAddTrackToPlaylistSaga,syncCollectionWorker— dispatchesaddOfflineEntries({ items: [..., { type: 'track' }, ...] }). The queue processor routes everytype === 'track'job to a singledownloadTrackWorker, which calls the two functions patched here. So both flows share the same broken code path.Changes
downloadTrackAudio: prefertrack.stream.url(with mirror substitution), keepgetTrackStreamUrl()+ manual signing as a last-resort fallback. MirrorsAudioPlayer.tsxlogic.downloadTrackCoverArt: best-effort — return silently if all URIs fail rather than throwing.buildMirrorUris(primary, mirrors)helper used by both audio and cover art.console.warnin the catch block ofdownloadTrackAsyncso future failures are diagnosable instead of silent.Test plan
stream.urlis unset.🤖 Generated with Claude Code