Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Error using Passport initializer: no method _devoke #90

Open
joegilley opened this Issue May 16, 2013 · 0 comments

Comments

Projects
None yet
1 participant

I have passport configured so that under standard circumstances (DB connections configured correctly) everything works as expected.

However, when I intentionally simulate a DB failure to test Passport's error callback, as written (this is defined within an initializer, as per the locomotivejs documentation):

passport.use(new LocalStrategy(
    function(username, password, done) {
        var User = self.db.models.User;
        User.find({ username: username }, function (err, users) {
            if (err) {
                debug(err);
                return done(err);
            }
            if (!user) {
                return done(null, false, 'User not found');
            }
            var user = users[0];
            user.validPassword(password, function (err, res) {
                if (!res) return done(null, false, 'Invalid password');
                else {
                    return done(null, user);
                }
            });
        });
    }));

I receive an error on the line return done(err):

TypeError: Object #<Context> has no method '_devoke'
    at Context.Controller.next.Controller.error [as next] /node_modules/locomotive/lib/locomotive/controller.js:336:8)

I've debugged to the point that from within the Controller code:

Controller.prototype.error = function(err) {
  var self = this;
  this._devoke(err, function(e) {
    return self.__next(e);
  });
}

self or this does NOT refer to a Controller object.

I figure that I must have something misconfigured, but I've triple checked Passport's documentation, and LocomotiveJS's. I would be happy to provide more code snippets for context if needed.

This is the full stack dump:

TypeError: Object #<Context> has no method '_devoke'
12:08:04 web.1       |     at Context.Controller.next.Controller.error [as next] (/Users/joma/git/BlueOcelot/node_modules/locomotive/lib/locomotive/controller.js:336:8)
12:08:04 web.1       |     at Context.actions.error (/Users/joma/git/BlueOcelot/node_modules/passport/lib/passport/context/http/actions.js:91:8)
12:08:04 web.1       |     at verified (/Users/joma/git/BlueOcelot/node_modules/passport-local/lib/passport-local/strategy.js:81:28)
12:08:04 web.1       |     at /Users/joma/git/BlueOcelot/config/initializers/03_passport.js:24:13
12:08:04 web.1       |     at /Users/joma/git/BlueOcelot/node_modules/orm/lib/ChainFind.js:108:13
12:08:04 web.1       |     at Query._callback (/Users/joma/git/BlueOcelot/node_modules/orm/lib/Drivers/DML/mysql.js:218:11)
12:08:04 web.1       |     at Query.Sequence.end (/Users/joma/git/BlueOcelot/node_modules/orm/node_modules/mysql/lib/protocol/sequences/Sequence.js:66:24)
12:08:04 web.1       |     at Query.ErrorPacket (/Users/joma/git/BlueOcelot/node_modules/orm/node_modules/mysql/lib/protocol/sequences/Query.js:89:8)
12:08:04 web.1       |     at Protocol._parsePacket (/Users/joma/git/BlueOcelot/node_modules/orm/node_modules/mysql/lib/protocol/Protocol.js:169:24)
12:08:04 web.1       |     at Parser.write (/Users/joma/git/BlueOcelot/node_modules/orm/node_modules/mysql/lib/protocol/Parser.js:62:12)

Note: Workaround commit I proposed in my fork does not work at all. The following workaround does work, but it is not a solution.

The offending code was not actually included in my original post. The actual problem comes from passing this.next to passport.authenticate(strategy, options, cb)(this.req, this.res, this.next). See below for contextual example:

// From the context of a Controller
var next = this.next;
passport.authenticate('local', {session: false}, function(err, user, info) {
    // This will throw an error regarding _devoke
    if (err) {return next();}
    if (!user) {
             ....
    }
})(this.req, this.res, next);

As far as I can make out, this.next is not the application-level function to the next middleware in the stack. It is the controller's abstraction in order to apply pre- and post- filters, before calling this.__next, the true application-level next function. I was able to workaround this issue by changing the parameter to the function returned by authenticate from this.next to this.__next. Though, this should not be a final solution and does not close this issue.

// From the context of a Controller
var next = this.__next;
passport.authenticate('local', {session: false}, function(err, user, info) {
    // This will not.
    if (err) {return next();}
    if (!user) {
             ....
    }
})(this.req, this.res, next);

cletusc added a commit to GamerPolls/gamerpolls.com that referenced this issue Nov 25, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment