Timeout feature in the axios library is not working

138,842

Solution 1

From this axios issue (Thanks to zhuyifan2013 for giving the solution), I've found that axios timeout is response timeout not connection timeout.

Let 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.

You've to use the following code

  const source = CancelToken.source();
  const timeout = setTimeout(() => {
    source.cancel();
    // Timeout Logic
  }, 10000);
  
  axios.get(ip + '/config', {cancelToken: source.token}).then((result) => {
    // Clear The Timeout
    clearTimeout(timeout);

    // Handle your response
  });

Please note that if you've valid connection, still the Timeout Logic block will get executed. So you've to clear the timeout.

Solution 2

This code works for me:

axios({
  method: "post",
  url: 'http://example.com/api',
  timeout: 1000 * 5, // Wait for 5 seconds
  headers: {
    "Content-Type": "application/json"
  },
  data: {
    id: 1234
  }
})
  .then(response => {
    const serverResponse = response.data;
    // do sth ...
  })
  .catch(error => {
    console.log(error);
});

If server won't respond in 5 seconds, it goes into catch block.

This is also useful: #1503

Solution 3

You need to create an instance of the axios http client:

const httpClient = axios.create();
httpClient.defaults.timeout = 500;

You can then use the httpClient as follows:

return httpClient.post(`${ROOT_URL}/login/${role}`, creds)
  .then(handleResponse)

On a side note you can also set the base url in the same config instead of using ${ROOT_URL}:

httpClient.defaults.baseURL = ROOT_URL

Solution 4

submitHashtag = async () => {
  const data = await axios.post('/pwa/basics.php',  {
    withCredentials: true,// if user login
    timeout: 30000
  })
  if (!data) {
    // action here
    alert('reload window')
    return
  }
 }

Solution 5

Shoutout to @arthankamal because his answer is the solution and this is just an update and follow-up.

The CancelToken is deprecated from v0.22.0, because they switched to AbortController, so I updated his code. See more here: https://axios-http.com/docs/cancellation

TrySending(data) {
    let abortController = new AbortController()
    const timeout = setTimeout(() => {
        abortController.abort()
        console.log("Aborted")
    }, 3000)

    return axios
        .post(
            apiURL,
            data,
            { signal: abortController.signal }
        )
        .then(response => {
            clearTimeout(timeout)
            return true
        })
        .catch(error => false)
}

This will return if it was succeeded or not.

Some notes:

  • Isn't worth trying using the .finally because it won't work
  • If it was canceled it will go straight to .catch() and the error will be { message: 'canceled' }
Share:
138,842
shet_tayyy
Author by

shet_tayyy

As a Senior Software Engineer III, I am part of the Consumer Product Platform organization, which is responsible for building the next-generation tools and services that serve consumer-ready product information to Nike experiences and back-end teams. I have: 7+ years of experience in planning, designing, and building a Javascript Application. Worked on building the HERE Design System Well aware of the Web components standards Worked on projects built around the JavaScript ecosystem namely React.js, React Native, Typescript, GraphQL, HTML5, CSS3, lit-html, open-wc, lit-element, polymer, Node.js, Express.js, Fastify.js MongoDB, Redux, Webpack 4, ESLint, Flow, etc. Experienced with React Ecosystem (React Router, Styled-components, Server-side rendering, Context API, React Hooks) Worked with GraphQL front-end clients like URQL and Apollo Client. Worked with Apollo and GraphQL Express server for the backend Experience with monitoring and tracing tools like Splunk, SignalFx, New Relic, etc. Used Docker and Dockerized containers for projects Proficient understanding of React Native Elements, React Native Paper, React Navigation, Core UI React, etc Proficient understanding of web markup including HTML5 & CSS3 Proficient understanding of cross-browser compatibility issues and ways to work around them. Handy with pre-processing tools and transpilers like Babel and SASS. Familiarity with testing frameworks like Jest, Enzyme, Mocha, Chai, and Sinon. An attitude for benchmarking and optimization. Proficient with Git and Gerritt. Handy with the shell and automation tools. Seasoned in maintaining code quality and organization. Handy with CI/CD pipeline configurations and commands Deployed applications successfully on AWS, Digital Ocean, and Heroku Strong verbal and written communication skills

Updated on July 05, 2022

Comments

  • shet_tayyy
    shet_tayyy almost 2 years

    I have set axios.defaults.timeout = 1000;

    I stopped the server that provides me with the APIs.

    But it takes more than 1s to timeout after sending a request.

    This is how my request looks:

    import axios from 'axios';
    axios.defaults.timeout = 1000;
    
    return axios.post(`${ROOT_URL}/login/${role}`, creds).then((response) => {
          console.log(response);
    
            if(response.status === 200) {
              // If login was successful, set the token in local storage
              localStorage.setItem(`${role}_log_toks`, JSON.stringify(response.data));
    
              // Dispatch the success action
              dispatch(receiveLogin(response.data));
    
              return response;
            }
          }).catch(err => {
            console.log(err);
            // If there was a problem, we want to
            // dispatch the error condition
            if(err.data && err.status === 404) {
              dispatch(loginError(err.data));
            } else {
              dispatch(loginError('Please check your network connection and try again.'));
            }
    
            return err;
          });
    

    I have also tried:

    return axios.post(`${ROOT_URL}/login/${role}`, creds, {timeout: 1000}).then...
    

    Axios doesn't stop fetching and after 5 - 10 minutes it finally shows network error. I understand that there are other techniques to handle timeout but why doesn't the timeout feature in axios work? What could be the reason that axios doesn't stop fetching?

    Axios version 0.9.1

    EDIT: As mentioned in the comments, I have also tried:

    import axios from 'axios';
    
    const httpClient = axios.create();
    
    httpClient.defaults.timeout = 500;
    
    return httpClient.post(`${ROOT_URL}/login/${role}`, creds)
      .then(handleResponse)
    
  • shet_tayyy
    shet_tayyy about 8 years
    1. I think you wanna return httpClient.post(${ROOT_URL}/login/${role}, creds) 2. Tried this as well. Didn't work. 3. Currently, I am using a technique mentioned by mislav here: github.com/github/fetch/issues/175 Works like a charm but I wanted the timeout provided by axios to work.
  • Clarkie
    Clarkie about 8 years
    I'm not sure why that isn't working for you. What version of axios are you using? Can you include your require / import statements and axios initialisation code above?
  • Daniel Cottone
    Daniel Cottone about 5 years
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
  • Zoe stands with Ukraine
    Zoe stands with Ukraine about 5 years
    @DanielCottone please review more carefully. This is also an answer
  • JillAndMe
    JillAndMe about 4 years
    It works but when I set timeout: 999999 an error: "net::ERR_CONNECTION_REFUSED" occurs rather than "timeout of 999999ms exceeded" when I set timeout greater than 5000
  • andrewgazelka
    andrewgazelka almost 4 years
    I want to add if you are having this issue with Angular, you can just add .pipe(timeout(TIMEOUT_MILLIS)) to the observable.
  • Mikhail Shemenyov
    Mikhail Shemenyov over 3 years
    axios uses XMLHttpRequest for browser env, and in case of > But you don't have internet connection - it will be a net::ERR_INTERNET_DISCONNECTED, so I think there is no real need to use axios (or any other) timeouts. It's applicable only on nodejs env. All other things browser can do. So if you really want to set a connection timeout, you can try to get a request object from axios and check for readyState - until it opened (1) - it's not connected yet.
  • pguardiario
    pguardiario over 3 years
    I don't understand why they don't just implement this in the library rather than give us a broken timeout option. They just closed the issue without fixing it...
  • Irfan wani
    Irfan wani almost 3 years
    If the server is closed, will the axios timeout work