1
0

fix: artwork cache never throws on body/disk failures

This commit is contained in:
2026-08-29 16:43:45 +02:00
parent 0faa74ae27
commit c1dd232a2f
2 changed files with 32 additions and 12 deletions

View File

@@ -22,20 +22,24 @@ export async function cacheArtwork(
): Promise<string | null> { ): Promise<string | null> {
if (!url) return null if (!url) return null
const key = createHash('sha256').update(url).digest('hex') const key = createHash('sha256').update(url).digest('hex')
mkdirSync(artworkDir, { recursive: true })
for (const ext of Object.values(EXT_BY_TYPE)) {
if (existsSync(path.join(artworkDir, key + ext))) return key + ext
}
let res: Response
try { try {
res = await fetchImpl(url) mkdirSync(artworkDir, { recursive: true })
for (const ext of Object.values(EXT_BY_TYPE)) {
if (existsSync(path.join(artworkDir, key + ext))) return key + ext
}
let res: Response
try {
res = await fetchImpl(url)
} catch {
return null
}
if (!res.ok) return null
const type = (res.headers.get('content-type') ?? '').split(';')[0]?.trim() ?? ''
const ext = EXT_BY_TYPE[type] ?? '.jpg'
const buf = Buffer.from(await res.arrayBuffer())
await writeFile(path.join(artworkDir, key + ext), buf)
return key + ext
} catch { } catch {
return null return null
} }
if (!res.ok) return null
const type = (res.headers.get('content-type') ?? '').split(';')[0]?.trim() ?? ''
const ext = EXT_BY_TYPE[type] ?? '.jpg'
const buf = Buffer.from(await res.arrayBuffer())
await writeFile(path.join(artworkDir, key + ext), buf)
return key + ext
} }

View File

@@ -75,4 +75,20 @@ describe('cacheArtwork', () => {
rmSync(dir, { recursive: true, force: true }) rmSync(dir, { recursive: true, force: true })
} }
}) })
it('returns null when the response body fails mid-download', async () => {
const dir = tempDir()
try {
const fetcher = (async () =>
new Response(new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([0xff]))
controller.error(new TypeError('network error mid-body'))
},
}), { status: 200, headers: { 'content-type': 'image/jpeg' } })) as unknown as typeof fetch
expect(await cacheArtwork(dir, 'https://x/abort.jpg', fetcher)).toBeNull()
} finally {
rmSync(dir, { recursive: true, force: true })
}
})
}) })