From 3633b4c5fa81ba5896620a09193ec61094c6fe0b Mon Sep 17 00:00:00 2001 From: Honey Date: Sun, 10 May 2026 18:15:24 +0200 Subject: [PATCH] fix: handle 429 rate-limit within timeout window - Cap per-retry wait at 15s (Spotify's Retry-After can be very long) - Increase global resolve timeout from 25s to 120s so retries can complete - Log rate-limit waits for visibility Co-Authored-By: Claude Sonnet 4.6 --- backend/novasonic-server.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/novasonic-server.js b/backend/novasonic-server.js index 48edaea..b194337 100644 --- a/backend/novasonic-server.js +++ b/backend/novasonic-server.js @@ -153,7 +153,9 @@ async function _spApi(path, token) { for (let attempt = 0; attempt < 4; attempt++) { const r = await _fetchTimeout(url, { headers: { Authorization: `Bearer ${token}` } }); if (r.status === 429) { - const wait = (parseInt(r.headers.get('Retry-After') || '5', 10) + 1) * 1000; + const retryAfter = parseInt(r.headers.get('Retry-After') || '5', 10); + const wait = Math.min(retryAfter + 1, 15) * 1000; // cap at 15s per retry + console.log(`[spotify] 429 rate-limited, waiting ${wait / 1000}s (Retry-After: ${retryAfter}s)`); await new Promise(res => setTimeout(res, wait)); continue; } @@ -305,7 +307,7 @@ app.post('/api/spotify/resolve', async (req, res) => { console.log(`[spotify/resolve] ${type} ${id}`); const timeout = new Promise((_, reject) => - setTimeout(() => reject(new Error('Zeitüberschreitung — Spotify API antwortet nicht (>25s)')), 25000) + setTimeout(() => reject(new Error('Zeitüberschreitung — Spotify API antwortet nicht (>120s)')), 120000) ); const data = await Promise.race([_resolveSpotify(type, id), timeout]); res.json(data);