-
Notifications
You must be signed in to change notification settings - Fork 24.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fetch] How to handle http request timeout #2556
Comments
Check out this discussion here: JakeChampion/fetch#175 - there is a solution implemented there that uses promises and seems nice. Lots of discussion going on about the fetch specification here: Another attempt at wrapping fetch to add this: whatwg/fetch#20 (comment) |
I really don't agree the above solutions. If fetch wait forever and you use setTimeout to reject the wrapper promise, then the fetch will hold the reference of the resolve and reject forever. |
I agree with @narychen, its a waste of memory. A big discussion is going on over here whatwg/fetch#20 and seems not have any solution. Here's what I did:
I now have a timeout of 10 seconds on my fetch requests. You can find my modified whatwg fetch.js file here: https://gist.github.com/kyle-ilantzis/e4521e6194f6c019b14ac91291feb348 You can find the setTimeout I added here: https://gist.github.com/kyle-ilantzis/e4521e6194f6c019b14ac91291feb348#file-whatwg-fetch-js-L440 You can modify 10 seconds to what ever you want here: https://gist.github.com/kyle-ilantzis/e4521e6194f6c019b14ac91291feb348#file-whatwg-fetch-js-L8 I any one is interested, here is the self.fetch.hack = true: |
Try https://github.com/benestudio/fetch/tree/feature/timeout
return fetch('/path', {timeout: 500}).then(function() {
// successful fetch
}).catch(function(error) {
// network request failed / timeout
}) This fork supports timout just like node-fetch. This way you can have timeouts runtime and bundle time also. Say goodbye to memory leaks. Hope it could be merged some sunny day. |
Any idea on how to use my fetch fork without forking and patching RN itself? |
@adambene you want your polyfill to overwrite react-native's polyfill. The first lines of fetch.js look like if (self.fetch) { Which will be true because the fetch function already exists. I suggest doing global.fetch = null; (I am not sure but i think it would be in global) Or changing the if to check for your fetch function such as if (fetch.hasTimeout) { return } |
@kyle-ilantzis whatwg-fetch is already imported before I could do anything: https://github.com/facebook/react-native/blob/292cc82d0ebc437a6f1cdd2e972b3917b7ee05a4/Libraries/Network/fetch.js |
@adambene yes whatwg-fetch is already imported. You want your whatwg-fetch-timeout to take precedence. I imagine you are importing yours? The problem is in your fetch.js file at the top of the file there is if (self.fetch) { |
@kyle-ilantzis I feel that whatwg-fetch-timeout should only be an extension to whatwg-fetch, so removing the fetch implementation check seems hacky to me. I've tried npm-shrinkwrap, but does not allow different package names only versions to be overridden. I am searching for a really maintainable and universal solution, because all my future projects are going to rely on fetch timeout to achieve robustness. That's why forking RN nor hacking whatwg-fetch is not a good option. (Edit: of course the most welcome would be a warm merge for the timeout feature.) |
It seems that there are 3 choices to override fetch in RN. And an extra. 1 Fork RNFork RN and rename the Well, it's a maintenance hell. 2 Import
|
Use
Create a new
Then replace your calls for |
Our team is currently using robinpowered/react-native-fetch-polyfill. It essentially provides It currently avoids writing to the global scope, but I suppose we could make that an option Sample Usageimport fetch from 'react-native-fetch-polyfill';
fetch(path, {timeout: 30 * 1000}) |
@adambene For me, importing 'whatwg-fetch-timeout' in all files did not work. I tried the idea by @clshortfuse. The following code did not work:
I used |
@adambene Also, why should whatwg-fetch-timeout be imported in all files? Since, we are patching, should it not be done in the main file, say index.android.js? |
@ajwhite I published react-native-fetch-timeout. It seems to set the timeout on xhr. But ontimeout callback is not triggered after the timeout has elapsed. |
@vijayst because RN hacks fetch into the global. See: react-native/Libraries/Core/InitializeCore.js Line 182 in dba133a
So it is not so straightforward to override that properly. |
For reference I have this question on StackOverflow: http://stackoverflow.com/questions/42495366/react-native-custom-fetch-polyfill |
@adambene you should have luck with react-native-fetch-polyfill with the following: import fetch from 'react-native-fetch-polyfill'
fetch(url, {timeout: 30 * 1000})
.then(response => {
// a successful response
})
.catch(error => {
// an error when the request fails, such as during a timeout
}) This doesn't replace the @vijayst I have not attempted to replace |
I am using Promise.race to work around this. Though the fetch promise won't be aborted. const delay = (timeout, error) => new Promise((resolve, reject) => setTimeout(() => reject(error), timeout))
const result = await Promise.race([fetchPromise, delay(30 * 1000, 'Timeout Error')] |
@ajwhite yeah, this package does the same: https://www.npmjs.com/package/whatwg-fetch-timeout repo/branch: https://github.com/benestudio/fetch/tree/feature/timeout |
@ajwhite solution work for me! (React Native 0.52 on Android) |
Hi, Guys
I currently ran into a issue that when using fetch to call remote data, I can't handle the timeout situation, if my not return successfully, it will wait forever.
I have google for awhile and I didn't find any good practice to handle, npm fetch doc says it has a timeout keyword in options object, but seems it didn't work at all.
how do you guys handle this situation?
The text was updated successfully, but these errors were encountered: