CORS noob
CORS noob

Reputation: 61

how to reject promise inside a then

I want to be able to reject the entire promise chain if anyone of the promise fails in a clean way. I want to "catch" this rejection and send an error notification. I have implemented it the following code:

let reportMetaData = api.ajaxGet(api.buildV3EnterpriseUrl('reports' + '/' + params.report_id))
  .catch(error => {
    if (error.status === constants.HTTP_STATUS.GATEWAY_TIMEOUT) {
      this.notify.error(this.translate('reports.report_timedout'), this.translate('reports.report_timedout_desc'));
    } else {
      this.send('error', error);
    }
  });

let aggregateData = reportMetaData.then(success => {
  try {
    return api.xmlRequest('GET', success.aggregationUrls.elements[0].url);
  } catch (error) {
    return Promise.reject();
  }
}).then(rawData => {
  try {
    return JSON.parse('{' + rawData + '}');
  } catch (error) {
    return Promise.reject();
  }
}, error => Promise.reject(error));

let aggregateReport = aggregateData.then(data => {
  if (!data || !data.report) {
    return Promise.reject();
  }
  return data.report;
}).catch(error =>{ 
    this.notify.error(this.translate('reports.report_timedout'), error); 
});

As you can see, it is super messy and complicated. Is there a way I can simplify this? I want the simplest way to reject the entire promise to fail if anyone promise fails. How do I do that from inside the then function? Also, it seems like the thrown error is bubbling up all the way to chrome console as uncaught error. Why does it bubble up even though I caught it?

Upvotes: 0

Views: 1069

Answers (3)

pizzarob
pizzarob

Reputation: 12029

You could use async functions to clean things up a bit. I think you could replace your code with the following.

async function processDataAndReport() {
  try {
    const data = await api.ajaxGet(api.buildV3EnterpriseUrl('reports' + '/' + params.report_id));
    const rawData = await api.xmlRequest('GET', data.aggregationUrls.elements[0].url);
    const { report } = JSON.parse(`{${rawData}}`);                         
  } catch(e) {
    // send notification
  }
}

Upvotes: 0

oneturkmen
oneturkmen

Reputation: 1330

Try aggregating everything under Promise.all(iterable).

More here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

If this is not quite what you wanted, take a look at Bluebird - fully featured promise library. Here

UPDATE: If you want to reject the entire promise if any of the promises inside the function fails, try implementing:

throw validationError;

Hope it works.

Upvotes: 0

quirimmo
quirimmo

Reputation: 9988

You need to use Promise.all() and provide the array of promises as input parameter. If one of those promises will fail, all the promises will not be resolved. Here the doc:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

And here a post on SO where you can read about them:

When to use promise.all()?

Upvotes: 1

Related Questions