zeodtr
zeodtr

Reputation: 11285

Bluebird promise: How to avoid the runaway promise warning in a nested function?

My code is as follows: (node.js code)

'use strict';

var Promise = require('bluebird');

function promised()
{
    return Promise.resolve();
}

function backgroundJob()
{
    return Promise.resolve();
}

function doBackgroundJob()
{
    // this is an intentional runaway promise.
    backgroundJob()
    .catch(function (err)
    {
        console.log('error', err);
    });
}

function test()
{
    return promised()
    .then(function ()
    {
        doBackgroundJob();
        return null;  // without this, bluebird displays the warning
    });
}

doBackgroundJob() does a background job, so it does not need to return a promise. But since it creates a promise, when the function is called in a then(), without an explicit return null in the then(), bluebird prints the following warning to the console. 'Warning: a promise was created in a handler but was not returned from it'.

This is somewhat unfair, since the caller does not need to know that the function uses a promise. How can I let bluebird to ignore the warning without return null in the then() in the caller?

I don't want to disable the warning, since it is quite useful.

Upvotes: 2

Views: 565

Answers (2)

Bergi
Bergi

Reputation: 665536

It depends:

  • doBackgroundJob is doing something asynchronous, so it should return a promise as usual to let the caller know when it is finished. Even if it already does all error-handling and guarantees to only fulfill the promise. The caller, knowing that it returns a promise, would use return null in then callbacks to avoid the warning.

    function doBackgroundJob() {
      return backgroundJob().catch(console.error);
    }
    
  • If the caller should not know what doBackgroundJobb is doing, you can create the promise asynchronously (so that Bluebird doesn't notice) and return nothing (so that the caller doesn't notice):

    function doBackgroundJob() {
      process.nextTick(() => {
        // this is an intentional runaway promise.
        backgroundJob().catch(console.error);
      });
    }
    

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371193

One possibility is to add the background .then separately, and return only the base promise:

function test() {
  const prom = promised();
  prom.then(doBackgroundJob);
  return prom;
}

while having doBackgroundJob return the promise (that proceeds to get discarded in this implementation):

function doBackgroundJob() {
  // this is an intentional runaway promise.
  return backgroundJob()
    .catch(function(err) {
      console.log('error', err);
    });
}

allowing other consumers of doBackgroundJob to possibly use the promise it returns if needed.

Upvotes: 1

Related Questions