Avoid new Request() in catch to prevent disturbed body errors

Extracts method/url directly from the input instead of constructing
a new Request in the catch block, which could fail if the body was
already consumed. Also adds a test with Request object input.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
This commit is contained in:
Fredrik Adelöw
2026-03-28 17:04:02 +01:00
parent 18c3dbadd6
commit cba19b13de
2 changed files with 24 additions and 2 deletions
@@ -36,6 +36,18 @@ describe('ClarifyFailuresFetchMiddleware', () => {
);
});
it('handles Request object input without constructing a new Request', async () => {
const inner = jest.fn().mockRejectedValue(new TypeError('Failed to fetch'));
const middleware = new ClarifyFailuresFetchMiddleware();
const request = new Request('https://example.com/api/data', {
method: 'POST',
body: JSON.stringify({ key: 'value' }),
});
await expect(middleware.apply(inner)(request)).rejects.toThrow(
new TypeError('Failed to fetch: POST https://example.com/api/data'),
);
});
it('does not modify other TypeErrors', async () => {
const error = new TypeError('some other error');
const inner = jest.fn().mockRejectedValue(error);
@@ -27,8 +27,18 @@ export class ClarifyFailuresFetchMiddleware implements FetchMiddleware {
return await next(input as any, init);
} catch (e) {
if (e instanceof TypeError && e.message === 'Failed to fetch') {
const request = new Request(input as any, init);
e.message = `Failed to fetch: ${request.method} ${request.url}`;
let method: string;
let url: string;
if (input instanceof Request) {
method = input.method;
url = input.url;
} else {
method = init?.method || 'GET';
url = String(input);
}
e.message = `Failed to fetch: ${method} ${url}`;
throw e;
}
throw e;