Release failed asset responses and refuse cancelled requests

This commit is contained in:
Sameh Khamis committed 2026-09-15 18:01:39 -07:00
1 parent 92526e9a92
commit f558a240d1
2 files changed
+30 -1

No files matched your search

+25
View File
@@ -338,3 +338,28 @@ test('byte and integrity checks run before rendering; adapter names never resolv
assert.equal(mounted, 1);
session.destroy();
});
test('failed responses release their body and an already-cancelled source sends no request', async () => {
let cancelled = 0,
requests = 0;
const source = createAssetDirectorySource({
baseUrl: 'https://example.org/packs/',
fetchImpl: async () => {
requests++;
return new Response(
new ReadableStream({
cancel() {
cancelled++;
},
}),
{ status: 403 },
);
},
});
await assert.rejects(source({ path: 'a.json' }), /unavailable/);
assert.equal(cancelled, 1);
const controller = new AbortController();
controller.abort();
await assert.rejects(source({ path: 'a.json', signal: controller.signal }));
assert.equal(requests, 1);
});
+5 -1
View File
@@ -19,6 +19,7 @@ export function createAssetDirectorySource({
);
return async ({ path, signal, maxBytes = PACK_LIMITS.bytes }) => {
validateAssetPath(path);
signal?.throwIfAborted();
const response = await fetchImpl(new URL(path, base).href, {
signal,
credentials: 'omit',
@@ -26,7 +27,10 @@ export function createAssetDirectorySource({
referrerPolicy: 'no-referrer',
cache: 'no-store',
});
if (!response.ok) throw new Error('Asset unavailable');
if (!response.ok) {
await response.body?.cancel().catch(() => {});
throw new Error('Asset unavailable');
}
const reader = response.body?.getReader();
if (!reader) throw new Error('Asset stream unavailable');
const chunks = [];