Skip to content

Commit

Permalink
Fix retries for requests with a body (#231)
Browse files Browse the repository at this point in the history
* Fix retries by cloning request before using it

Fixes #217

* Add test for reusing body on retry

* Fix request counter assertion
  • Loading branch information
sholladay committed Feb 1, 2020
1 parent 78814e7 commit 55b2535
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
4 changes: 2 additions & 2 deletions index.js
Expand Up @@ -389,10 +389,10 @@ class Ky {
}

if (this._options.timeout === false) {
return globals.fetch(this.request);
return globals.fetch(this.request.clone());
}

return timeout(globals.fetch(this.request), this._options.timeout, this.abortController);
return timeout(globals.fetch(this.request.clone()), this._options.timeout, this.abortController);
}

/* istanbul ignore next */
Expand Down
48 changes: 43 additions & 5 deletions test/browser.js
Expand Up @@ -4,6 +4,8 @@ import {serial as test} from 'ava';
import createTestServer from 'create-test-server';
import withPage from './helpers/with-page';

const pBody = util.promisify(body);

test('prefixUrl option', withPage, async (t, page) => {
const server = await createTestServer();
server.get('/', (request, response) => {
Expand Down Expand Up @@ -73,22 +75,24 @@ test('throws TimeoutError even though it does not support AbortController', with
response.end();
});

server.get('/endless', () => {});
server.get('/slow', (request, response) => {
setTimeout(() => {
response.end('ok');
}, 1000);
});

await page.goto(server.url);
await page.addScriptTag({path: './test/helpers/disable-abort-controller.js'});
await page.addScriptTag({path: './umd.js'});

// TODO: make set a timeout for this evaluation so we don't have to wait 30s
const error = await page.evaluate(url => {
window.ky = window.ky.default;

const request = window.ky(`${url}/endless`, {timeout: 500}).text();
const request = window.ky(`${url}/slow`, {timeout: 500}).text();
return request.catch(error_ => error_.toString());
}, server.url);
t.is(error, 'TimeoutError: Request timed out');

// A note from @szmarczak: await server.close() hangs on my machine
await server.close();
});

Expand Down Expand Up @@ -180,12 +184,13 @@ test('throws if does not support ReadableStream', withPage, async (t, page) => {
});

test('FormData with searchParams', withPage, async (t, page) => {
t.plan(2);

const server = await createTestServer();
server.get('/', (request, response) => {
response.end();
});
server.post('/', async (request, response) => {
const pBody = util.promisify(body);
const requestBody = await pBody(request);

t.regex(requestBody, /bubblegum pie/);
Expand All @@ -211,6 +216,8 @@ test('FormData with searchParams', withPage, async (t, page) => {
});

test('headers are preserved when input is a Request and there are searchParams in the options', withPage, async (t, page) => {
t.plan(2);

const server = await createTestServer();
server.get('/', (request, response) => {
response.end();
Expand All @@ -236,3 +243,34 @@ test('headers are preserved when input is a Request and there are searchParams i

await server.close();
});

test('retry with body', withPage, async (t, page) => {
let requestCount = 0;

const server = await createTestServer();
server.get('/', (request, response) => {
response.end('zebra');
});
server.put('/test', async (request, response) => {
requestCount++;
await pBody(request);
response.sendStatus(502);
});

await page.goto(server.url);
await page.addScriptTag({path: './umd.js'});

const error = await page.evaluate(url => {
window.ky = window.ky.default;
const request = window.ky(url + '/test', {
body: 'foo',
method: 'PUT',
retry: 2
}).text();
return request.catch(error_ => error_.toString());
}, server.url);
t.is(error, 'HTTPError: Bad Gateway');
t.is(requestCount, 2);

await server.close();
});

0 comments on commit 55b2535

Please sign in to comment.