Reputation: 1254
Having issues trying to get timeout
method of axios working.
For testing: I setup a intentionally bad API endpoint: it accepts a request, throws an error (Eg: throw new Error(“testing for timeout”)
) and intentionally does nothing else.
My client app (reactJS) hangs once I make a call to the test API endpoint - I expected it to timeout within 2 seconds (my set timeout). I can verify that the app is making contact with server. Its only when I kill my test API server that my client app immediately continues.
Sample code:
const axios = require('axios')
const test1Press = async () => {
try
{
await axios.post('https://mynodeserver.com/api/debug/throw', {timeout: 2000})
console.log("post call passed")
}
catch (err)
{
console.log("post call failed")
}
}
EDIT (~2020):
On further research, looks like axios timeout
is only for response timeouts but not connection timeouts. Suggested solutions for connection timeouts are cancellation methods (e.g. signal
, cancelToken (deprecated)
):
Tested this and working:
const source = CancelToken.source();
try {
let response = null;
setTimeout(() => {
if (response === null) {
source.cancel();
}
}, 2000);
response = await axios.post('/url',null,{cancelToken: source.token});
// success
} catch (error) {
// fail
}
Upvotes: 34
Views: 169263
Reputation: 2984
As indicated in @arthankamal answer, timeout
property is only responsible for response timeouts but not connection timeouts. To address connection timeouts, use axios's cancellation methods. Adding examples below based on newer signal
property (cancelToken
is deprecated ).
Example with signal
and AbortSignal.timeout() built-in [requires nodejs 17.3+]:
axios({
method: 'get',
url: '/foo/bar',
timeout: 5000,
signal: AbortSignal.timeout(5000) //Aborts request after 5 seconds
})
.then(function(response) {
//...
});
Example with signal
and a timeout helper function:
function newAbortSignal(timeoutMs) {
const abortController = new AbortController();
setTimeout(() => abortController.abort(), timeoutMs || 0);
return abortController.signal;
}
axios({
method: 'get',
url: '/foo/bar',
timeout: 5000,
signal: newAbortSignal(5000) //Aborts request after 5 seconds
})
.then(function(response) {
//...
});
Upvotes: 8
Reputation: 5411
With await axios.post('/debug/throw', {timeout: 2000})
, actually you send the payload {timeout: 2000}
to the server, not set the timeout to 2 seconds. See an example here.
I tested with another syntax of axios and it worked
const test1Press = async () => {
console.log("test1 pressed")
// obviously not the actual url in this stackoverflow post
axios.defaults.baseURL = 'http://localhost:9000'
console.log("pre call")
console.log(new Date().toUTCString());
try {
await axios({
method: 'post',
url: '/',
timeout: 2000 // only wait for 2s
})
console.log(new Date().toUTCString());
console.log("post call passed")
}
catch (err) {
console.log(new Date().toUTCString());
console.log("post call failed")
}
}
test1Press();
On the server-side, I wait for 5 seconds to have the timeout error on the client-side
const http = require('http');
const server = http.createServer(function (req, res) {
setTimeout(function () {
res.write('Hello World!');
res.end();
}, 5 * 1 * 1000); // after 5s
})
.listen(9000);
Running the code above gives me the timeout error after 2 seconds
test1 pressed
pre call
Mon, 28 Jun 2021 09:01:54 GMT
Mon, 28 Jun 2021 09:01:56 GMT
post call failed
EDIT I tested to create the instance of axios, this gives me the same result:
const test1Press = async () => {
console.log("test1 pressed")
// obviously not the actual url in this stackoverflow post
const instance = axios.create({
baseURL: 'http://localhost:9000',
timeout: 2000,
});
console.log("pre call")
console.log(new Date().toUTCString());
try {
await instance.post('/');
console.log(new Date().toUTCString());
console.log("post call passed")
}
catch (err) {
console.log(new Date().toUTCString());
console.log("post call failed")
}
}
test1Press();
Upvotes: 30
Reputation: 1462
Let's say you've requested the URL through axios and server is taking long time to respond, in this case the axios timeout will work.
But you don't have internet connection or the IP address or domain name that you're requesting not there, in this case axios timeout will not work.
See original answer for solution
Upvotes: 0