Skip to content

Commit

Permalink
Merge pull request #6576 from whymarrh/cancellable-fetch
Browse files Browse the repository at this point in the history
Add custom fetch wrapper with abort on timeout
  • Loading branch information
whymarrh authored May 7, 2019
2 parents 891fbb7 + b3c7cb3 commit da599c9
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 1 deletion.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
"@storybook/addon-info": "^3.4.2",
"@storybook/addon-knobs": "^3.4.2",
"@storybook/react": "^3.4.2",
"abortcontroller-polyfill": "^1.3.0",
"addons-linter": "^1.3.4",
"babel-core": "^6.24.1",
"babel-eslint": "^8.0.0",
Expand Down
1 change: 1 addition & 0 deletions test/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ global.log = log

// fetch
global.fetch = require('isomorphic-fetch')
require('abortcontroller-polyfill/dist/polyfill-patch-fetch')

// dom
require('jsdom-global')()
Expand Down
8 changes: 7 additions & 1 deletion ui/app/helpers/utils/fetch-with-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import {
loadLocalStorageData,
saveLocalStorageData,
} from '../../../lib/local-storage-helpers'
import http from './fetch'

const fetch = http({
timeout: 30000,
})

export default function fetchWithCache (url, opts, cacheRefreshTime = 360000) {
const currentTime = Date.now()
const cachedFetch = loadLocalStorageData('cachedFetch') || {}
const { cachedUrl, cachedTime } = cachedFetch[url] || {}
if (cachedUrl && currentTime - cachedTime < 360000) {
if (cachedUrl && currentTime - cachedTime < cacheRefreshTime) {
return cachedFetch[url]
} else {
cachedFetch[url] = { cachedUrl: url, cachedTime: currentTime }
Expand All @@ -17,6 +22,7 @@ export default function fetchWithCache (url, opts, cacheRefreshTime = 360000) {
body: null,
method: 'GET',
mode: 'cors',
...opts,
})
}
}
25 changes: 25 additions & 0 deletions ui/app/helpers/utils/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* global AbortController */

export default function ({ timeout = 120000 } = {}) {
return function _fetch (url, opts) {
return new Promise(async (resolve, reject) => {
const abortController = new AbortController()
const abortSignal = abortController.signal
const f = fetch(url, {
...opts,
signal: abortSignal,
})

const timer = setTimeout(() => abortController.abort(), timeout)

try {
const res = await f
clearTimeout(timer)
return resolve(res)
} catch (e) {
clearTimeout(timer)
return reject(e)
}
})
}
}
54 changes: 54 additions & 0 deletions ui/app/helpers/utils/fetch.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import assert from 'assert'
import nock from 'nock'

import http from './fetch'

describe('custom fetch fn', () => {
it('fetches a url', async () => {
nock('https://api.infura.io')
.get('/money')
.reply(200, '{"hodl": false}')

const fetch = http()
const response = await (await fetch('https://api.infura.io/money')).json()
assert.deepEqual(response, {
hodl: false,
})
})

it('throws when the request hits a custom timeout', async () => {
nock('https://api.infura.io')
.get('/moon')
.delay(2000)
.reply(200, '{"moon": "2012-12-21T11:11:11Z"}')

const fetch = http({
timeout: 123,
})

try {
await fetch('https://api.infura.io/moon').then(r => r.json())
assert.fail('Request should throw')
} catch (e) {
assert.ok(e)
}
})

it('should abort the request when the custom timeout is hit', async () => {
nock('https://api.infura.io')
.get('/moon')
.delay(2000)
.reply(200, '{"moon": "2012-12-21T11:11:11Z"}')

const fetch = http({
timeout: 123,
})

try {
await fetch('https://api.infura.io/moon').then(r => r.json())
assert.fail('Request should be aborted')
} catch (e) {
assert.deepEqual(e.message, 'Aborted')
}
})
})

0 comments on commit da599c9

Please sign in to comment.