fix(dz): implement alternative track fallback for error 2002

("Track token has
no sufficient rights on requested media").

Previous behavior:
- Only tried format fallback (FLAC → MP3_320 → MP3_128)
- Used same track token for all format attempts
- Failed when error 2002 occurred even if alternative tracks existed

New behavior:
- When error 2002 occurs, fetches FALLBACK.SNG_ID and gets fresh token
- Retries with same format but different track ID
- Loops through all alternative track IDs before trying format fallback
- Only after exhausting alternatives does it fall back to lower quality formats
This commit is contained in:
2025-10-03 11:43:11 -04:00
parent 0ef56c3bed
commit 6fff93fe45
2 changed files with 148 additions and 63 deletions

View File

@@ -438,7 +438,7 @@ export class DeezerAPI {
}
// Get track download URL
async getTrackDownloadUrl(trackToken: string, format: string, licenseToken: string, retryCount: number = 0): Promise<string | null> {
async getTrackDownloadUrl(trackToken: string, format: string, licenseToken: string, retryCount: number = 0): Promise<{ url: string | null; errorCode?: number; errorMessage?: string }> {
console.log('[DEBUG] Getting track download URL...', { trackToken, format, licenseToken });
try {
@@ -479,19 +479,19 @@ export class DeezerAPI {
if (trackData.errors && trackData.errors.length > 0) {
const error = trackData.errors[0];
console.error('[ERROR] Deezer media API error:', error);
// Return null to trigger fallback, don't throw - let caller handle it
return null;
// Return error details so caller can handle alternative track fallback
return { url: null, errorCode: error.code, errorMessage: error.message };
}
if (trackData.media && trackData.media.length > 0) {
const url = trackData.media[0].sources[0].url;
console.log('[DEBUG] Got download URL:', url);
return url;
return { url };
}
}
console.error('[ERROR] No download URL in response:', result);
return null;
return { url: null };
} catch (error: any) {
console.error('[ERROR] Failed to get track download URL:', error);