-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
Response timeout does not work as expected #459
Comments
Temporary workaround: var Timeout = require('stream-timeout')
client.get('/stop-writing-body-halfway', {
responseType: 'stream',
}).then((response) => {
const { data } = response
return new Promise((resolve, reject) => {
const bufs = []
data
.pipe(new Timeout(200))
.on('timeout', () => {
data.req.abort()
const err = new Error('timeout')
err.data = Buffer.concat(bufs)
reject(err)
})
data.on('data', (buf) => {
bufs.push(buf)
})
data.on('end', () => resolve(Buffer.concat(bufs)))
})
}) |
In the current implementation, the timeout is canceled when the response headers have been received, but any suggestions on how to improve this are welcome. |
Shouldn't the timeout be cleared on https://github.com/mzabriskie/axios/blob/master/lib/adapters/http.js#L161 |
@dtryon I'm not sure I understand what you mean. My request was that we have a timeout for response bodies because sometimes servers shutdown unexpectedly and you don't want to be forever stuck waiting for a response that will never arrive. |
@olalonde Yes, exactly. At the moment, the current timeout is cleared before the response body has been completely received: https://github.com/mzabriskie/axios/blob/master/lib/adapters/http.js#L116 The timeout gets cleared before the body stream is processed. Instead the timeout could be be cleared later (when the body has been completely received). |
Any solution for this ? I'm having the same problem, response data is halfway received but after the defined timeout, it just stops and there are no signal a timeout has been triggered. Usually we want timeout to be applied on request. If the data start to be fetched, timeout shouldn't apply (or might we use a responseTimeout variable in the config ?). |
@Rewieer @ALL, Even I was facing this issue. I used to stop the server where I send API requests and then I used to make a request. It used to take minutes for displaying the error message. Then I found a solution provided by someone in the issues. I do not remember the issue number or title. (Please attach the issue here if someone recognizes the title of the issue from the code I am providing) This is what I did:
|
On a related note, I wrote https://github.com/blockai/broken-http-server to help test those sort of things in my code. Could be helpful in axios tests. |
@srahulprdxn sounds very good for request timeout, but any clue for response timeout ? What if I receive a success response ? It will trigger the timeout, see the success status code and just consider things are done even through the JSON isn't entirely parsed. |
I've come to this solution. const defaultConfig = {
method: 'GET',
params: null,
data: null,
timeout: 2000
};
const fetch = (url, method, config) => {
const finalConfig = Object.assign({}, defaultConfig, config);
return axios({
url,
method,
params: finalConfig.params, // QUERY
data: finalConfig.data, // REQUEST
headers: finalConfig.headers,
timeout: finalConfig.timeout,
}).then(response => {
if(response.headers['content-length'] > response.request._response.length){
response.__incomplete = true;
}
return response;
});
};
` |
@srahulprdxn This is interesting, but unless I'm mistaken, this solution will not abort the underlying request (and socket). |
@srahulprdxn The post relating the issue thing is #56 |
@Rewieer Awesome. Thanks a lot for finding this post. I had any issues with response. Hence, can't comment anything on that. Sorry. |
Faced with the same issue (axios 0.12.0). I am working with the server that doesn't close connections properly and as a result - axios' Promise never resolves (even with timeout being set). I solved the problem wrapping axios request by own Promise and rejecting it by own timeout. I believe timeout should reject promise, counting in total request + response time. I mean if timeout is 5 secs, request took 3 secs and the response is receiving more than 2 secs - timeout should break this axios request. Is there any chance the behavior of axios timeout would be changed? :) |
Happens for me from time to time on different requests even if |
We've been using the following trick in one of our projects:
Can a similar logic be implemented in Axios (perhaps with a new |
It looks like Shall I put a small PR together to implement this fix? This will enable wider usage of Axios in our server-side projects. |
In case it's useful to anyone I've been patching the behaviour of const requestTimeoutInterceptor = config => {
if (config.timeout === undefined || config.timeout === 0) {
return config;
}
const source = axios.CancelToken.source();
setTimeout(() => {
source.cancel(`Cancelled request. Took longer than ${config.timeout}ms to get complete response.`);
}, config.timeout);
// If caller configures cancelToken, preserve cancelToken behaviour.
if (config.cancelToken) {
config.cancelToken.promise.then(cancel => {
source.cancel(cancel.message);
});
}
return { ...config, cancelToken: source.token };
};
axios.interceptors.request.use(requestTimeoutInterceptor); |
See: #4209 |
I wanna clarify the behaviour of the timeout. Does timeout resolve or reject the promise? I just got a request that timed out and yet my .then() got called |
The following code doesn't work as expected (no timeout error is fired):
After a few minutes, a response is resolved despite
Content-Length
not having been reached and the server not explicitly closing the connection. Edit: never mind the connection is probably closed after 2 mins because of https://nodejs.org/api/http.html#http_server_timeoutMy server never closes the connection and stops writing the body half way:
Is the timeout only for the request, not for the response?
The text was updated successfully, but these errors were encountered: