isomorphic-fetch
isomorphic-fetch copied to clipboard
any possible way to include timeout on fetch()?
couldn't find the docs for this repository... my code looks like this:
fetch('/test', { method: 'POST', body: data })
.then(function(response) {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(function(response) {
console.log(response)
});
would like to fake a server response for the fetch... any ideas?
thanks in advance
+1 not sure how to add timeout
yes please, add a timeout
option
+1, please add timeout option
you can do as fellow: `fetch("/test", { method: 'POST', body: data })
.then(function(response) {
if (response.status >= 400) {
const error = new error("Bad response from server")
error.response = response
error.message = "your error message,you can swith the status and set the message"
throw error
}
return response.json();
}).then(function(response) {
console.log(response)
}).catch(function(e) {
if (!e.response) {
e.message = "response time out!"
}
return Promise.reject(e);
})`
This isn't handling a timeout for me...
There is an optional "timeout" property you can pass in the options.
fetch(url, {method: 'GET', timeout: 5000})
.then(response => {
if (response.status >= 400) {
reject({
code: response.status,
message: response.statusText
});
} else {
resolve(response.json());
}
})
.catch(reject);
``
Create a timeoutPromise wrapper...
function timeoutPromise(timeout, err, promise) {
return new Promise(function(resolve,reject) {
promise.then(resolve,reject);
setTimeout(reject.bind(null,err), timeout);
});
}
You can then wrap any promise...
timeoutPromise(100, new Error('Timed Out!'), fetcn(...))
.then(...)
.catch(...)
It won't actually cancel an underlying connection, but will allow you to timeout a promise.
When a client timeout occured, it's very important to cancel the http request.
The fetch
api will offer this functionality in a near future with the FetchController.
By the way, I solved this neatly in react-native by using redux-saga.
@raarts how redux-saga solve it? Can you post code in here?
Inside a saga, race the fetch call with a timeout like this:
try {
const { timeout, response } = yield race({
timeout: call(delay, 10000),
response: call(fetch, '<your endpoint>', { parms}),
});
if (timeout) {
console.log('network timeout')
} else {
if (response.status === 200) {
// success
} else {
// API error
}
}
}
catch(error) {
// Other error by fetch
}
Kinda late here, this is based off of @tyler-canton code he posted up here
function fetch_timeout(url, options = {}) {
/*
* fetches a request like the normal fetch function
* but with a timeout argument added.
*/
let timeout = options.timeout || 30000;
let timeout_err = {
ok: false,
status: 408
};
return new Promise(function(resolve, reject) {
fetch(url, options).then(resolve, reject);
setTimeout(reject.bind(null, timeout_err), timeout);
});
}
// use
fetch_timeout("http://google.com", {timeout: 500}).then(data => {
// response here
}).catch(err => {
// got an error, maybe timeout?
})
This lets you use fetch like how you would normally, but just have an added timeout option. Thanks @tyler-canton!
You might want to change the timeout_err to be an actual error you can check for, for my case this was perfect for what i needed to do.
@kiorq I think you meant to do this:
fetch_timeout("http://google.com", {timeout: 500})
Rather than:
fetch("http://google.com", {timeout: 500})
Also your example doesn't help because all you do is a fetch. Something like the following would be beneficial:
fetchTimeout(copyOfUrl, {timeout: 3}) .then(data => console.log("Data: ", data)) .catch(reason => console.error("Caught error: ", reason.message));
In my case data came back immediately as undefined and I never get the error message after 3 seconds. Tried to fetch this large JSON file:
https://raw.githubusercontent.com/zemirco/sf-city-lots-json/master/citylots.json
This is how you should be handling abort:
const controller = new AbortController()
const signal = controller.signal
setTimeout(() => {
controller.abort()
}, 1000)
fetch(url, { signal })
For anyone else who gets hung up on Fetch not having timeout you could use the node-fetch rather than native Fetch API. In a lot of cases a timeout isn't necessary but it is necessary if you want to ensure TCP/IP connections close out and don't just have an open socket for some undetermined time. Here's what I ended up doing with node-fetch Works really well:
https://github.com/github/fetch/issues/617
this should be in userLand
If AbortController is not the solution for you, you can take a peek at this answer on stackoverflow (https://stackoverflow.com/questions/46946380/fetch-api-request-timeout). I found it quite useful !
FWIW, I've opened an issue https://github.com/whatwg/fetch/issues/951 with a proposal for a timeout
option that solves 90% of use cases, in case anyone's interested. I think it's super important to add to make sure calls to fetch
(or res.json()
) don't hang indefinitely.
@ianstormtaylor You really made a number on every single repo that uses the fetch API. you should only have brought it up with whatwg and then the rest will follow.