fix: 25s backend timeout + 30s frontend timeout on Spotify resolve
Extracts resolve logic into _resolveSpotify() and wraps it in Promise.race with a 25s timer so the backend always sends a response even if undici's AbortSignal.timeout silently fails on blocked sockets. Also reduces frontend timeout from 90s to 30s. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
7d38fdf601
commit
76271c1e54
2 files changed
+24
-30
No files matched your search
+23
-29
@@ -223,24 +223,15 @@ app.get('/api/health', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/api/spotify/resolve', async (req, res) => {
|
||||
const { url } = req.body;
|
||||
if (!url) return res.status(400).json({ error: 'url required' });
|
||||
try {
|
||||
const { type, id } = parseSpotifyUrl(url);
|
||||
async function _resolveSpotify(type, id) {
|
||||
const token = await fetchSpotifyToken();
|
||||
|
||||
if (type === 'track') {
|
||||
const t = await _spApi(`/tracks/${id}`, token);
|
||||
const artist = _spArtistName(t.artists);
|
||||
const artUrl = _spArtwork(t);
|
||||
return res.json({
|
||||
type: 'track',
|
||||
name: t.name || '',
|
||||
artist,
|
||||
artworkUrl: artUrl,
|
||||
tracks: [_spTrackItem(t, t.album?.name, artUrl, artist)],
|
||||
});
|
||||
return { type: 'track', name: t.name || '', artist, artworkUrl: artUrl,
|
||||
tracks: [_spTrackItem(t, t.album?.name, artUrl, artist)] };
|
||||
}
|
||||
|
||||
if (type === 'album') {
|
||||
@@ -248,13 +239,8 @@ app.post('/api/spotify/resolve', async (req, res) => {
|
||||
const artist = _spArtistName(album.artists);
|
||||
const artUrl = _spArtwork(album);
|
||||
const trackItems = await _spAllAlbumTracks(id, token);
|
||||
return res.json({
|
||||
type: 'album',
|
||||
name: album.name || '',
|
||||
artist,
|
||||
artworkUrl: artUrl,
|
||||
tracks: trackItems.map(t => _spTrackItem(t, album.name, artUrl, artist)),
|
||||
});
|
||||
return { type: 'album', name: album.name || '', artist, artworkUrl: artUrl,
|
||||
tracks: trackItems.map(t => _spTrackItem(t, album.name, artUrl, artist)) };
|
||||
}
|
||||
|
||||
if (type === 'playlist') {
|
||||
@@ -262,18 +248,26 @@ app.post('/api/spotify/resolve', async (req, res) => {
|
||||
const owner = pl.owner?.display_name || '';
|
||||
const artUrl = _spArtwork(pl);
|
||||
const { tracks: trackItems, skippedLocal } = await _spAllPlaylistTracks(id, token);
|
||||
return res.json({
|
||||
type: 'playlist',
|
||||
name: pl.name || '',
|
||||
artist: owner,
|
||||
artworkUrl: artUrl,
|
||||
description: pl.description || '',
|
||||
skippedLocal,
|
||||
tracks: trackItems.map(t => _spTrackItem(t, null, null, null)),
|
||||
});
|
||||
return { type: 'playlist', name: pl.name || '', artist: owner, artworkUrl: artUrl,
|
||||
description: pl.description || '', skippedLocal,
|
||||
tracks: trackItems.map(t => _spTrackItem(t, null, null, null)) };
|
||||
}
|
||||
|
||||
res.status(400).json({ error: `Unbekannter Typ: ${type}` });
|
||||
throw new Error(`Unbekannter Typ: ${type}`);
|
||||
}
|
||||
|
||||
app.post('/api/spotify/resolve', async (req, res) => {
|
||||
const { url } = req.body;
|
||||
if (!url) return res.status(400).json({ error: 'url required' });
|
||||
try {
|
||||
const { type, id } = parseSpotifyUrl(url);
|
||||
console.log(`[spotify/resolve] ${type} ${id}`);
|
||||
|
||||
const timeout = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Zeitüberschreitung — Spotify API antwortet nicht (>25s)')), 25000)
|
||||
);
|
||||
const data = await Promise.race([_resolveSpotify(type, id), timeout]);
|
||||
res.json(data);
|
||||
} catch(e) {
|
||||
console.error('[spotify/resolve]', e.message);
|
||||
if (e.message.includes('403') && e.message.includes('/playlists/')) {
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ export async function resolveSpotifyLink() {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ url }),
|
||||
signal: AbortSignal.timeout(90000),
|
||||
signal: AbortSignal.timeout(30000),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
|
||||
Reference in new issue
Block a user