Skip to content

Commit

Permalink
fix: make timeouts stricter (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
achingbrain authored May 1, 2020
1 parent 3bdfeea commit bbcd1eb
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
40 changes: 26 additions & 14 deletions src/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,29 @@ const timeout = (promise, ms, abortController) => {
return promise
}

return new Promise((resolve, reject) => {
const timeoutID = setTimeout(() => {
reject(new TimeoutError())

abortController.abort()
}, ms)
const start = Date.now()

promise
.then((result) => {
return new Promise((resolve, reject) => {
const after = (next) => {
return (res) => {
clearTimeout(timeoutID)
const time = Date.now() - start

resolve(result)
}, (err) => {
clearTimeout(timeoutID)
if (time >= ms) {
abortController.abort()
reject(new TimeoutError())
return
}

reject(err)
})
if (next) {
next(res)
}
}
}
const timeoutID = setTimeout(after(), ms)

promise
.then(after(resolve), after(reject))
})
}

Expand Down Expand Up @@ -138,7 +144,13 @@ class HTTP {
opts.headers.set('content-type', 'application/json')
}

const response = await timeout(fetch(url, opts), opts.timeout, this.abortController)
const response = await timeout(fetch(url, {
...opts,

// node-fetch implements it's own timeout in an addition to the spec so do not
// pass the timeout value on, otherwise there are two sources of timeout errors
timeout: undefined
}), opts.timeout, this.abortController)

if (!response.ok && opts.throwHttpErrors) {
if (opts.handleError) {
Expand Down
6 changes: 6 additions & 0 deletions test/http.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ describe('http', function () {
expect(rsp).to.be.deep.eq({ test: 'one' })
})

it('makes a GET request with a really short timeout', function () {
return expect(HTTP.get(`${process.env.ECHO_SERVER}/redirect?to=${encodeURI(`${process.env.ECHO_SERVER}/echo/query?test=one`)}`, {
timeout: 1
})).to.eventually.be.rejectedWith().instanceOf(HTTP.TimeoutError)
})

it('makes a JSON request', async () => {
const req = await HTTP.post(`${process.env.ECHO_SERVER}/echo`, {
json: {
Expand Down

0 comments on commit bbcd1eb

Please sign in to comment.