William M.
William M.

Reputation: 379

Axios handle error using interceptor (js promises)

I am using an interceptor in axios to check for errors.

service.interceptors.response.use(
  response => response,
  error => {
    const originalRequest = error.config

    if (!error.response) {
      // No network connectivity
    }
  }
)

My request looks like this

service.post('endpoint').then(response => {
  // Successful request
}).catch(error => {
  // Handle error
})

In case there is any error such as an unsuccessful status code (e. g. 400), I wan't to handle the error in the catch part of the second code example. However, if there is a network issue, I wan't to handle the error in the first code example. In that case neither then, nor catch of the second code example should be called. How can I achieve this?

Upvotes: 6

Views: 9564

Answers (1)

Manuel Spigolon
Manuel Spigolon

Reputation: 13150

When you have a promise chain already in place you can't stop the flow:

const axios = require('axios')

axios.interceptors.response.use(
  response => response,
  manageErrorConnection
)

// here you have created a promise chain that can't be changed:
axios.get('http://localhost:3000/user?ID=12345')
  .then(handleResponse)
  .catch(handleError)

function manageErrorConnection(err) {
  if (err.response && err.response.status >= 400 && err.response.status <= 500) {
    // this will trigger the `handleError` function in the promise chain
    return Promise.reject(new Error('Bad status code'))
  } else if (err.code === 'ECONNREFUSED') {
    // this will trigger the `handlerResponse` function in the promise chain
    // bacause we are not returning a rejection! Just an example
    return 'nevermind'
  } else {
    // this will trigger the `handleError` function in the promise chain
    return Promise.reject(err)
  }
}

function handleResponse(response) {
  console.log(`handleResponse: ${response}`);
}

function handleError(error) {
  console.log(`handleError: ${error}`);
}

So in order to run an optional step, you need to:

  1. put logic in the handler, to skip it
  2. put the handler in the chain when it is needed (I would just avoid that since it is "spaghetti software")

  1. put the logic in the handler example
// .... changing this line ...
    return Promise.reject('nevermind')
// ....

function handleError(error) {
  if (error === 'nevermind') {
    return
  }
  console.log(`handleError: ${error}`);
}

This logic could be isolated:

axios.get('http://google.it/user?ID=12345')
  .then(handleResponse)
  .catch(shouldHandleError)
  .catch(handleError)

function manageErrorConnection(err) { return Promise.reject('nevermind') }

function handleResponse(response) { console.log(`handleResponse: ${response}`); }

function shouldHandleError(error) {
  if (error === 'nevermind') {
    // this stop the chain
    console.log('avoid handling');
    return
  }
  return Promise.reject(error)
}

function handleError(error) { console.log(`handleError: ${error}`); }

Upvotes: 5

Related Questions