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.
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();
});
};