Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluebird warning "A promise was created in a handler but was not returned from it"

I get the warning about not returning a created promise from Bluebird and I do not understand why and how I should rewrite my code.

(I have tried reading about the warning at Bluebird API page and the anti-pattern page as I suspect this is what I'm doing)

In my view.js file:

var express = require('express'),
    router = express.Router(),
    settings = myReq('config/settings'),
    Sets = myReq('lib/Sets'),
    log = myReq('lib/utils').getLogger('View');

router.get('/:setId/', function(req, res, next) {
    var
        setId = req.params.setId,  
        user = req.user,
        set = new Sets(setId, user);

    log.info('Got a request for set: ' + setId);

    // The below line gives the warning mentioned
    set.getSet().then(function(output) {
        res.send(output);

    }).error(function(e){
        log.error(e.message, e.data);
        res.send('An error occurred while handling set:' + e.message);
    });

});

module.exports = router;

In my Sets.js file I have:

var
    Promise = require('bluebird'),
    OE = Promise.OperationalError,
    settings = myReq('config/settings'),
    UserData = myReq('lib/userData'),
    log = myReq('lib/utils').getLogger('sets'),
    errorToSend = false;

module.exports = function(setId, user) {
    var 
        sets = myReq('lib/utils').getDb('sets');

    return {

        getSet : function() {

            log.debug('Getting set')

            return sets.findOneAsync({
                setId:setId
            }).then(function(set){
                if ( set ) {
                    log.debug('got set from DB');
                } else {
                    set = getStaticSet(setId);
                    if ( ! set ) {
                        throw new OE('Failed getting db records or static template for set: ' + setId );
                    }
                    log.debug('got static set');
                }

                log.debug('I am handling set')

                if ( ! checkSet(set) ) {
                    var e = new OE('Failed checking set');
                    e.data = set;
                    throw e;
                }

                return {
                    view : getView(set),
                    logic : set.logic,
                    canEdit : true,
                    error : errorToSend
                };

            });
        }
    };
};

So the line in my view.js file with "set.getSet()" gives the warning about not returning the created promise. It seems like this script still does what I expect it to do, but I do not understand why I get the warning.

Stacktrace:

Warning: a promise was created in a handler but was not returned from it
    at Object.getSet (C:\dev\infoscrn\lib\Sets.js:36:25)
    at C:\dev\infoscrn\routes\view.js:39:20
    at Layer.handle [as handle_request] (C:\dev\infoscrn\node_modules\express\lib\router\layer.js:82:5)
    at next (C:\dev\infoscrn\node_modules\express\lib\router\route.js:110:13)
    at Route.dispatch (C:\dev\infoscrn\node_modules\express\lib\router\route.js:91:3)
    at Layer.handle [as handle_request] (C:\dev\infoscrn\node_modules\express\lib\router\layer.js:82:5)
    at C:\dev\infoscrn\node_modules\express\lib\router\index.js:267:22
    at param (C:\dev\infoscrn\node_modules\express\lib\router\index.js:340:14)
    at param (C:\dev\infoscrn\node_modules\express\lib\router\index.js:356:14)
    at Function.proto.process_params (C:\dev\infoscrn\node_modules\express\lib\router\index.js:400:3)
    at next (C:\dev\infoscrn\node_modules\express\lib\router\index.js:261:10)
    at Function.proto.handle (C:\dev\infoscrn\node_modules\express\lib\router\index.js:166:3)
    at router (C:\dev\infoscrn\node_modules\express\lib\router\index.js:35:12)
    at Layer.handle [as handle_request] (C:\dev\infoscrn\node_modules\express\lib\router\layer.js:82:5)
    at trim_prefix (C:\dev\infoscrn\node_modules\express\lib\router\index.js:302:13)
    at C:\dev\infoscrn\node_modules\express\lib\router\index.js:270:7
    at Function.proto.process_params (C:\dev\infoscrn\node_modules\express\lib\router\index.js:321:12)
    at next (C:\dev\infoscrn\node_modules\express\lib\router\index.js:261:10)
    at C:\dev\infoscrn\node_modules\express\lib\router\index.js:603:15
    at next (C:\dev\infoscrn\node_modules\express\lib\router\index.js:246:14)
like image 592
Karl Erik Steinbakk Avatar asked Dec 19 '15 12:12

Karl Erik Steinbakk


2 Answers

First, try and update all your dependencies. There's been a recent version of Bluebird, which fixed an issue involving this warning.

Next, make sure you return from all your handlers.

Then, if you still get the warning (like I do) you can disable this specific warning. I chose to do so by setting BLUEBIRD_W_FORGOTTEN_RETURN=0 in my environment.

like image 112
Gunar Gessner Avatar answered Nov 15 '22 14:11

Gunar Gessner


Don't disable warnings. They're there for a reason.

The typical pattern is that if your onfulfill or onreject handler causes a Promise to be constructed, it will return that Promise (or some chain derived from it) from the handler, so that the chain adopts the state of that Promise.

So Bluebird is keeping track of when it is running one of your handler functions, and also keeping track of when it's Promise constructor is called. If it determines that a Promise was created at any point while your handler is running (that includes anywhere down in the callstack), but that Promise was not returned from your handler, it issues this warning because it thinks you probably forgot to write the return statement.

So if you legitimately don't care about the Promise that was created inside the handler, all you have to do is explicitly return something from your handler. If you don't care about what is returned from your handler (i.e., if you don't care what value the Promise fulfills with), then simply return null. Whatever you return, the explicit return (specifically, a return value other than undefined) tells Bluebird that you think you know what you're doing, and it won't issue this warning.

like image 22
brianmearns Avatar answered Nov 15 '22 14:11

brianmearns