Search code examples
javascriptpromisebluebirdknex.js

Same promises gives two different results


Good morning people.

I have been working on a function that gives me problems.

.then(function (values2) {
  function generateReports () {

    return Promise.all([
        Reports.InterCompaniesUsa                   .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.InterCompaniesCanada                .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Design                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Production                          .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),

        Reports.MonthlySalesByCustomers             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Cashing                             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Income                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.AgedTrialBalance                    .generate(periodToClose.date_start, periodToClose.date_end, {save: true})
    ])
  }

  function generateAllAccountStatement () {
    db.select('invoices.customer_id_customer')
      .distinct('invoices.customer_id_customer')
      .from('invoices')
      .where({
        'invoices.invoice_status': 'INVOICED'
      })
      .andWhere(function () {
        this.where('invoices.invoice_date', '<=', periodToClose.date_end)
          .andWhere('invoices.invoice_date', '>=', periodToClose.date_start)
      })
      .orWhere(function () {
        this.where('invoices.invoice_date', '<=', periodToClose.date_start)
          .andWhere('invoices.balance', '<>', 0)
      })
      .then(function (arrOfCustomersWithInvoicesThisMonthOrWithPostponeBalance) {
        arrOfCustomersWithInvoicesThisMonthOrWithPostponeBalance.forEach(function (oneCustomer) {
          Reports.AccountStatement.generate(periodToClose.date_end, oneCustomer.customer_id_customer, {save: true});
        })
      })
      .catch(function (err) {
        console.error(err)
      })
  }

  return Promise.all([generateReports(), generateAllAccountStatement()])
})
.then(function (allIsDoneYes) {
  return res.json(allIsDoneYes);
})
.catch(function (err) {
  console.error(err);
  return res.status(500).send(err);
})

My problem is: the function generateReports doesn't resolve. I tried to isolate each promises in there all they are all ok. When I replace the function with this code below, it's working and I wonder why (because they look pretty much the same to me).

function generateReports () {
    Promise.all([
        Reports.InterCompaniesUsa                   .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.InterCompaniesCanada                .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Design                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Production                          .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),

        Reports.MonthlySalesByCustomers             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Cashing                             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Income                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.AgedTrialBalance                    .generate(periodToClose.date_start, periodToClose.date_end, {save: true})
    ])
    .then(result => {
        return result;
    })
    .catch(err => {
        console.error(err);
    })
}

Solution

  • It could be that when you are running so many parallel

    Reports.*.generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
    

    queries parallel and if that generate code has some errors or weird dependencies they might fill your pool and block the whole application.

    Try to add DEBUG=knex:* environment variable to your shell and run your report generation code:

    await generateReports();
    

    And see if you can spot anything weird with database connections or to see the place where resolving that promise hangs.

    Also you can try to make at first smaller generateReports implementation, which generates only one report and then add more reports to it until you find the combination where promise wont resolve anymore.