mirror of
https://github.com/bigchaindb/js-bigchaindb-driver.git
synced 2024-11-24 11:01:28 +01:00
feat: ensure timeout and request are properly cleared
This commit is contained in:
parent
c5fe1346b9
commit
8c0c72622d
@ -9,14 +9,14 @@ import { vsprintf } from 'sprintf-js'
|
|||||||
import formatText from './format_text'
|
import formatText from './format_text'
|
||||||
import stringifyAsQueryParam from './stringify_as_query_param'
|
import stringifyAsQueryParam from './stringify_as_query_param'
|
||||||
|
|
||||||
const fetch = fetchPonyfill(Promise)
|
const fetch = fetchPonyfill({ Promise })
|
||||||
|
|
||||||
export function ResponseError(message, status, requestURI) {
|
export function ResponseError(message, status, requestURI) {
|
||||||
this.name = 'ResponseError'
|
this.name = 'ResponseError'
|
||||||
this.message = message
|
this.message = message
|
||||||
this.status = status
|
this.status = status
|
||||||
this.requestURI = requestURI
|
this.requestURI = requestURI
|
||||||
this.stack = (new Error()).stack
|
this.stack = new Error().stack
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseError.prototype = new Error()
|
ResponseError.prototype = new Error()
|
||||||
@ -26,17 +26,27 @@ ResponseError.prototype = new Error()
|
|||||||
* Timeout function following https://github.com/github/fetch/issues/175#issuecomment-284787564
|
* Timeout function following https://github.com/github/fetch/issues/175#issuecomment-284787564
|
||||||
* @param {integer} obj Source object
|
* @param {integer} obj Source object
|
||||||
* @param {Promise} filter Array of key names to select or function to invoke per iteration
|
* @param {Promise} filter Array of key names to select or function to invoke per iteration
|
||||||
|
* @param {AbortController} controller AbortController instance bound to fetch
|
||||||
* @return {Object} TimeoutError if the time was consumed, otherwise the Promise will be resolved
|
* @return {Object} TimeoutError if the time was consumed, otherwise the Promise will be resolved
|
||||||
*/
|
*/
|
||||||
function timeout(ms, promise) {
|
function timeout(ms, promise, controller) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
setTimeout(() => {
|
const nodeTimeout = setTimeout(() => {
|
||||||
|
controller.abort()
|
||||||
const errorObject = {
|
const errorObject = {
|
||||||
message: 'TimeoutError'
|
message: 'TimeoutError',
|
||||||
}
|
}
|
||||||
reject(new Error(errorObject))
|
reject(new Error(errorObject))
|
||||||
}, ms)
|
}, ms)
|
||||||
promise.then(resolve, reject)
|
promise
|
||||||
|
.then((res) => {
|
||||||
|
clearTimeout(nodeTimeout)
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
clearTimeout(nodeTimeout)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,25 +98,30 @@ function handleResponse(res) {
|
|||||||
* @return {Promise} If requestTimeout the timeout function will be called. Otherwise resolve the
|
* @return {Promise} If requestTimeout the timeout function will be called. Otherwise resolve the
|
||||||
* Promise with the handleResponse function
|
* Promise with the handleResponse function
|
||||||
*/
|
*/
|
||||||
export default function baseRequest(url, {
|
export default function baseRequest(
|
||||||
jsonBody,
|
url,
|
||||||
query,
|
{
|
||||||
urlTemplateSpec,
|
jsonBody, query, urlTemplateSpec, ...fetchConfig
|
||||||
...fetchConfig
|
} = {},
|
||||||
} = {}, requestTimeout) {
|
requestTimeout = 0
|
||||||
|
) {
|
||||||
let expandedUrl = url
|
let expandedUrl = url
|
||||||
|
|
||||||
if (urlTemplateSpec != null) {
|
if (urlTemplateSpec != null) {
|
||||||
if (Array.isArray(urlTemplateSpec) && urlTemplateSpec.length) {
|
if (Array.isArray(urlTemplateSpec) && urlTemplateSpec.length) {
|
||||||
// Use vsprintf for the array call signature
|
// Use vsprintf for the array call signature
|
||||||
expandedUrl = vsprintf(url, urlTemplateSpec)
|
expandedUrl = vsprintf(url, urlTemplateSpec)
|
||||||
} else if (urlTemplateSpec &&
|
} else if (
|
||||||
|
urlTemplateSpec &&
|
||||||
typeof urlTemplateSpec === 'object' &&
|
typeof urlTemplateSpec === 'object' &&
|
||||||
Object.keys(urlTemplateSpec).length) {
|
Object.keys(urlTemplateSpec).length
|
||||||
|
) {
|
||||||
expandedUrl = formatText(url, urlTemplateSpec)
|
expandedUrl = formatText(url, urlTemplateSpec)
|
||||||
} else if (process.env.NODE_ENV !== 'production') {
|
} else if (process.env.NODE_ENV !== 'production') {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn('Supplied urlTemplateSpec was not an array or object. Ignoring...')
|
console.warn(
|
||||||
|
'Supplied urlTemplateSpec was not an array or object. Ignoring...'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,11 +139,17 @@ export default function baseRequest(url, {
|
|||||||
if (jsonBody != null) {
|
if (jsonBody != null) {
|
||||||
fetchConfig.body = JSON.stringify(jsonBody)
|
fetchConfig.body = JSON.stringify(jsonBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestTimeout) {
|
if (requestTimeout) {
|
||||||
return timeout(requestTimeout, fetch.fetch(expandedUrl, fetchConfig))
|
const controller = new AbortController()
|
||||||
|
const { signal } = controller
|
||||||
|
return timeout(
|
||||||
|
requestTimeout,
|
||||||
|
fetch.fetch(expandedUrl, { ...fetchConfig, signal }),
|
||||||
|
controller
|
||||||
|
)
|
||||||
.then(handleResponse)
|
.then(handleResponse)
|
||||||
} else {
|
} else {
|
||||||
return fetch.fetch(expandedUrl, fetchConfig)
|
return fetch.fetch(expandedUrl, fetchConfig).then(handleResponse)
|
||||||
.then(handleResponse)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user