NodeJS Bluebird promise created in a handler but was not returned from it

Bill Gilson

I have the following nodejs code as an express middleware function

Middleware.is_authenticated = function(req, res, next)
{
    if(req.system_session == undefined || req.system_session.login_status == false) return res.status(401).send({errors: true, error: 'invalid_session', session: req.system_session}).end();

    Session.validate_session(req.system_session, req.ip, req.headers['user-agent'])

    .then(function(session)
    {
        return next();
    })

    .catch(function(err)
    {
        req.system_session.destroy();
        return res.status(401).send({errors: true, error: err.message, session: req.system_session}).end();
    });
};

My Session.validate_session code:

Session.validate_session = function(user, user_ip, user_agent)
{
    return new Promise(function(resolve, reject)
    {
        if(user.user_id == null || user.user_name == null || user.user_rank == null || user.user_session == null || user_ip == null || user_agent == null) return reject(new Error('invalid_session'));

        new api_session({user_session: user.user_session}).fetch({columns: ['user_id', 'user_name', 'user_rank', 'user_session', 'user_ip', 'user_agent']})

        .then(function(result)
        {
            if(result == null) return reject(new Error('invalid_session'));

            return result.toJSON();
        })

        .then(function(session)
        {
            if(session == null || session.user_id != user.user_id || session.user_name != user.user_name || session.user_rank != user.user_rank || session.user_ip != user_ip || session.user_agent != user_agent) return reject(new Error('invalid_session'));

            return resolve(session);
        })

        .catch(function(err)
        {
            return reject(err);
        });
    });
};

Everything is working exactly as it should, everything is executing flawlessly with the database, as well as resolving the 'next' route and even displaying the response. But no matter what I try I keep getting 'a promise was created in a handler but was not returned from it'

Warning: a promise was created in a handler at middleware.js:12:11 but was not returned from it

at new Promise (/Users/Bill/Documents/app/node_modules/bluebird/js/release/promise.js:77:14)
at Object.Permission.permission_list (/Users/Bill/Documents/app/app/security/permission.js:8:10)
at PermissionService.permission_list (/Users/Bill/Documents/app/app/http/services/permission_service.js:6:14)
at Layer.handle [as handle_request] (/Users/Bill/Documents/app/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/Bill/Documents/app/node_modules/express/lib/router/route.js:131:13)
at /Users/Bill/Documents/app/app/http/middleware.js:12:11
at processImmediate [as _immediateCallback] (timers.js:383:17)

From previous event:
at Middleware.is_authenticated (/Users/Bill/Documents/app/app/http/middleware.js:10:4)
at Layer.handle [as handle_request] (/Users/Bill/Documents/app/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/Bill/Documents/app/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/Bill/Documents/app/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/Bill/Documents/app/node_modules/express/lib/router/layer.js:95:5)
at /Users/Bill/Documents/app/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/Bill/Documents/app/node_modules/express/lib/router/index.js:330:12)
at next (/Users/Bill/Documents/app/node_modules/express/lib/router/index.js:271:10)
at clientSession (/Users/Bill/Documents/app/node_modules/client-sessions/lib/client-sessions.js:630:5)
at Layer.handle [as handle_request] (/Users/Bill/Documents/app/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/Bill/Documents/app/node_modules/express/lib/router/index.js:312:13)
at /Users/Bill/Documents/app/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/Users/Bill/Documents/app/node_modules/express/lib/router/index.js:330:12)
at next (/Users/Bill/Documents/app/node_modules/express/lib/router/index.js:271:10)
at SendStream.error (/Users/Bill/Documents/app/node_modules/express/node_modules/serve-static/index.js:121:7)
at emitOne (events.js:77:13)
at SendStream.emit (events.js:169:7)
at SendStream.error (/Users/Bill/Documents/app/node_modules/express/node_modules/send/index.js:275:17)
at SendStream.onStatError (/Users/Bill/Documents/app/node_modules/express/node_modules/send/index.js:392:12)

If anyone has any solutions that would be great. I have many promises in my project that are all extremely similar and those are all working great but I just can't get my head around this one.

Bergi

This comes from the mix of promise-based code (Session.validate_session) with callback-based code (next). It would be expected that the next() call either is not asynchronous (doesn't create any promises) or returns that promise, which it doesn't (blame express).

There are two ways to avoid the warning:

  • Let express do the error handling, and call next with an error if one occurs. In this case, you can use the .asCallback method:

    Middleware.is_authenticated = function(req, res, next) {
        if (req.system_session == undefined || req.system_session.login_status == false)
            var promise = Promise.reject(new Error('invalid_session'));
        else
            var promise = Session.validate_session(req.system_session, req.ip, req.headers['user-agent']);
    
        promise.asCallback(next);
    };
    
  • As the warning explanation says, you can explicitly return null instead of returning the undefined value that next() yields:

    Middleware.is_authenticated = function(req, res, next) {
        if (req.system_session == undefined || req.system_session.login_status == false)
            var promise = Promise.reject(new Error('invalid_session'));
        else
            var promise = Session.validate_session(req.system_session, req.ip, req.headers['user-agent'])
            .catch(function(err) {
                req.system_session.destroy();
                throw err;
            });
    
        promise.then(function(session) {
            next();
            return null;
        }, function(err) {
            res.status(401).send({errors: true, error: err.message, session: req.system_session}).end();
        });
    };
    

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

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

Simple example for "a promise was created in a handler but was not returned from it"

Promise created in handler but not returned

Why do I not get the warning "a promise was created in a handler but was not returned from it"?

(node:5540) Warning: a promise was created in a handler but was not returned from it

Result from database with promise is not returned properly in nodeJS

How is a Promise That Is Returned From A Resolve Handler Mapped To The Return Value of 'then'?

returned promise is undefined in nodejs

Using bluebird promise not working in my created example

NodeJs - Bluebird promise.resolve(value) is undefined

Nodejs Promise not resolving/no data returned

bluebird: access value returned from last then callback

Convert promise code from Q to bluebird

Get Bluebird Promise from async await functions

NodeJS redirect from handler

resolve or reject promise when "request/ajax " response is 'success' in nodejs bluebird

Cannot get my promise to return in nodejs / mongoose / bluebird

nodejs sqlite3 db.run as a bluebird promise

Promise never returned (never finishes) - NodeJS

Promise returned by NodeJS Async function is undefined

Promise not returned from recursive function

Filtering an array returned from Promise

Objects returned from promise are undefined

Acces to jQuery $.get URL from Bluebird Promise object

Javascript - can't resolve this 'warning: promise was created in a handler'

Bluebird Promise: error is not a function

Bluebird Promise Cancellation

Convert promise to bluebird

Adding a method to Bluebird promise