最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - axios.all spread and catch all - Stack Overflow

programmeradmin3浏览0评论

I'm using .all method of popular library 'axios' for handling my ajax requests.

But how can I handle errors in case all requests got 404?

for example:

axios.all([
        axios.get('http://some_url'),
        axios.get('http://another_url'),
      ])
        .then(axios.spread((someUrl, anotherUrl) => {
         // ... boring stuff goes there
        }))
        .catch(() => {
         //... error goes there
        });

So, seems only one error has ben "catched".

How can I catch them all? Or maybe there any kinda .finally?

I'm using .all method of popular library 'axios' for handling my ajax requests.

But how can I handle errors in case all requests got 404?

for example:

axios.all([
        axios.get('http://some_url'),
        axios.get('http://another_url'),
      ])
        .then(axios.spread((someUrl, anotherUrl) => {
         // ... boring stuff goes there
        }))
        .catch(() => {
         //... error goes there
        });

So, seems only one error has ben "catched".

How can I catch them all? Or maybe there any kinda .finally?

Share Improve this question asked Feb 8, 2018 at 8:45 WebArtisanWebArtisan 4,22712 gold badges47 silver badges66 bronze badges 0
Add a comment  | 

3 Answers 3

Reset to default 11

The problem (as you already know) is that you will get into catch block as soon as the first promise rejects, making it impossible to collect all failed responses in the same catch. However, you still can handle failed promises manually to aggregate errors and throw afterwards.

Check it this will work for you:

const promises = [
  axios.get('http://some_url'),
  axios.get('http://another_url'),
]
const promisesResolved = promises.map(promise => promise.catch(error => ({ error })))

function checkFailed (then) {
  return function (responses) {
    const someFailed = responses.some(response => response.error)

    if (someFailed) {
      throw responses
    }

    return then(responses)
  }
}

axios.all(promisesResolved)
  .then(checkFailed(([someUrl, anotherUrl]) => {
    console.log('SUCCESS', someUrl, anotherUrl)
  }))
  .catch((err) => {
    console.log('FAIL', err)
  });

You will get into catch block if at least one of the promises fails. You can find one which one by checking err array of responses.

I don't think this is possible due to the fail fast behaviour of Promise.all. If any of your requests fail, they will automatically be the culprit and the result in the catch.

    Promise.all([
      Promise.reject(Error('1')),
      Promise.reject(Error('2')),
      Promise.reject(Error('3'))
    ]).then((results) => {
      console.log(results)
    }, (error) => {
      console.log(error.message)
    })

This resulting code will always print 1 as it is the first to fail.I think a similar feature was requested on the repo and they said it wasn't possible.

I was going to leave this as a comment but don't have a high enough reputation yet.

The solution from @dfsq did not work for me because it throws all requests when one has an error. I changed his code so every request either gets resolved or throws an error. @dfsq please review this answer if the code is correct, since I built it on your solution.

const promises = [
  axios.get('http://some_url'),
  axios.get('http://another_url'),
]
const promisesResolved = promises.map(promise => promise.catch(error => ({ error })))

function checkFailed (then) {
    return function (responses) {
        responses.forEach(response => {
            if (response.error)
                throw response;
            return then(response);
        })
    }
}

axios.all(promisesResolved)
  .then(checkFailed(response => {
    console.log('SUCCESS', response)
  }))
  .catch((err) => {
    console.log('FAIL', err)
  });
发布评论

评论列表(0)

  1. 暂无评论