fix: lrclib rate limit — exact first, then 2 parallel searches; check HTTP 200

3 simultaneous requests were hitting lrclib rate limiter.
Now: exact match alone → if no content, 2 parallel searches.
Also check response.status === 200 before parsing to avoid treating
404/429 error bodies as valid empty lyrics responses.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-15 21:46:09 +02:00
1 parent d7f8b301ab
commit eb5b0ea360
2 files changed
+55 -47

No files matched your search

+24 -14
View File
@@ -174,25 +174,35 @@ async function _loadNpLyrics(songId) {
return;
}
// Fire all three lrclib requests in parallel — total wait = slowest single request
const exactP = new URLSearchParams({ artist_name: artist, track_name: title });
// 1. lrclib exact match — single request, only trust HTTP 200
const exactP = new URLSearchParams({ artist_name: artist, track_name: title });
if(album) exactP.set('album_name', album);
if(dur) exactP.set('duration', dur);
const artistP = new URLSearchParams({ track_name: title });
if(artist) artistP.set('artist_name', artist);
const titleP = new URLSearchParams({ track_name: title });
const [exactData, artistData, titleData] = await Promise.all([
safeJson(fetch(`https://lrclib.net/api/get?${exactP}`, { signal: SIG() })),
safeJson(fetch(`https://lrclib.net/api/search?${artistP}`, { signal: SIG() })),
safeJson(fetch(`https://lrclib.net/api/search?${titleP}`, { signal: SIG() })),
]);
let result = null;
try {
const r = await fetch(`https://lrclib.net/api/get?${exactP}`, { signal: SIG() });
if(r.status === 200) {
const d = await r.json();
if(d?.syncedLyrics || d?.plainLyrics || d?.instrumental) result = d;
}
} catch {}
if(token !== _lyricsLoadToken) return;
let result = (exactData?.syncedLyrics || exactData?.plainLyrics ? exactData : null)
?? bestMatch(artistData, dur)
?? bestMatch(titleData, dur);
// 2+3. lrclib search — artist+title and title-only in parallel (2 requests, not 3)
if(!result) {
const artistP = new URLSearchParams({ track_name: title });
if(artist) artistP.set('artist_name', artist);
const titleP = new URLSearchParams({ track_name: title });
const [artistData, titleData] = await Promise.all([
safeJson(fetch(`https://lrclib.net/api/search?${artistP}`, { signal: SIG() })),
safeJson(fetch(`https://lrclib.net/api/search?${titleP}`, { signal: SIG() })),
]);
result = bestMatch(artistData, dur) ?? bestMatch(titleData, dur);
}
if(token !== _lyricsLoadToken) return;
// NetEase fallback — good for Asian/Japanese music
if(!result?.syncedLyrics && !result?.plainLyrics) {