fix: keep transit snapshot parsing within request lifetime

This commit is contained in:
Sameh Khamis committed 2026-09-15 08:01:30 -07:00
1 parent 3155e4e0bf
commit 30e01890e7
2 files changed
+46 -3

No files matched your search

+17 -3
View File
@@ -13,9 +13,23 @@ export function createTransitSource({
signal?.throwIfAborted();
if (typeof feedId !== 'string' || !feedId || feedId.length > 160)
throw new TypeError('A transit feed identifier is required');
return fetchImpl(`/api/transit/vehicles/${encodeURIComponent(feedId)}`, {
signal,
headers: { Accept: 'application/json' },
return Promise.resolve(
fetchImpl(`/api/transit/vehicles/${encodeURIComponent(feedId)}`, {
signal,
headers: { Accept: 'application/json' },
}),
).then((response) => {
signal?.throwIfAborted();
return {
ok: response.ok,
status: response.status,
headers: response.headers,
async json() {
const body = await response.json();
signal?.throwIfAborted();
return body;
},
};
});
},
};
+29
View File
@@ -110,3 +110,32 @@ test('source retains history validation and never retries through another transp
);
assert.equal(calls, 1);
});
test('snapshot cancellation covers headers and body parsing', async () => {
for (const phase of ['headers', 'body']) {
const controller = new AbortController();
const source = createTransitSource({
fetchImpl: async () => {
if (phase === 'headers') controller.abort();
return {
ok: true,
status: 200,
headers: new Headers(),
json: async () => {
controller.abort();
return { vehicles: [] };
},
};
},
});
await assert.rejects(
async () => {
const response = await source.requestSnapshot('mbta', {
signal: controller.signal,
});
await response.json();
},
{ name: 'AbortError' },
);
}
});