node.js - Why mongoose.model.create's Callback Isn't Executed from within Express 3.x HTTP Request Handler (connect-mongodb is the cause, actually) -
to put problem stright in code:
expressapp.get('/', function requesthandler(req, res) { usermongoosemodel.create(userpropertiesdict, never_called_callback); console.log('this printed fine browser awaits response forever.'); }
express 3.x, mongoose 3.x.
imprtant details of initialization:
mongoose.connect(mongourl); var mongostore = require('connect-mongodb'); // not 'connect-mongo', sic! var store = new mongostore({db: mongoose.connection.db}, resulthandler);
you can see whole code @ github.
here minified version of main script there:
var express = require('express'), mongoose = require('mongoose') mongostore = require('connect-mongodb'); var app = express(); var mongourl = 'mongodb://localhost/problem_users'; var port = 9001; console.log('connecting mongodb...'); mongoose.connect(mongourl); schema = mongoose.schema; attributes = { email: { type: string, required: true, unique: true } }; schema = new schema(attributes, { strict: true }); var user = mongoose.model('user', schema); app.configure(function() { app.use(express.cookieparser()); app.use(express.session({ secret: 'what bad can happen if share secret?', maxage: new date(date.now() + 60*60*1000), store: new mongostore({ db: mongoose.connection.db }, function(err) { return console.log(err || 'connect-mongodb setup ok'); }) })); return app; }); app.get('/', function(req, res) { console.log('ready register new user...'); var userpropertiesdict = { email: 'some.email@example.com', } console.log('calling user.create...'); user.create(userpropertiesdict, function(err, doc) { console.log('why message not printed @ all?'); var done = process.stdout.write('are stuck @ flushing?'); if (!done) { // stdout blocked? process.stdout.on('drain', _) } }); console.log('response over. message printed @ end , hang afterwards.'); }); app.listen(port); console.log("listening on port ", port); console.log("mongodb url ", mongourl); console.log('navigate browser http://localhost:%d', port);
note problem includes connect-mongodb
, not connect-mongo
. switching connect-mongodb
connect-mongo
resolves problem in more elegant way, should try first. following related connect-mongodb
only.
i have figured out problem doesn't involve express
@ all. deals order in mongoose
connection , connect-mongodb
session initialized.
when connect-mongodb
session initialized, database must connected. mongoose.connect
executed asynchronously can easy run problem when session initialized bofore connection finished (as did).
the sad side reason connect-mongodb
doesn't throw or pass error.
you can see right , wrong ways of mongoose
, connect-mongodb
initializion in code below.
var mongoose = require('mongoose') mongostore = require('connect-mongodb'); var mongourl = 'mongodb://localhost/problem_users'; console.log("mongodb: url ", mongourl); console.log('mongodb: connecting...'); /* // wrong way of using mongoose connect-mongodb. // source below source of problem. mongoose.connect(mongourl, function(err) { console.log('this not printed.'); if (err) { console.log('this not printed either.'); throw err; } }); new mongostore({ db: mongoose.connection.db }, function(err) { // line below prints 2. console.log('mongodb: readystate %d (2 = connecting, 1 = connected)', mongoose.connection.readystate); return console.log(err || 'connect-mongodb setup ok'); }) */ // right way of using mongoose connect-mongodb. mongoose.connect(mongourl, {auto_reconnect: true, native_parser: true}, function(err) { new mongostore({ db: mongoose.connection.db }, function(err) { // line below usuall prints 1. console.log('mongodb: readystate %d (2 = connecting, 1 = connected)', mongoose.connection.readystate); return console.log(err || 'connect-mongodb setup ok'); }); }); console.log('mongodb: connected.') schema = mongoose.schema; attributes = { email: { type: string, required: true, unique: true } }; var schema = new schema(attributes); var user = mongoose.model('user', schema); function createuser(callback) { var userpropertiesdict = { email: 'some.email@example.com', } console.log('calling user.create...'); user.create(userpropertiesdict, callback); } function never_called_callback(err, doc) { console.log('why message not printed @ all?'); var done = process.stdout.write('are stuck @ flushing?'); if (!done) { // stdout blocked? process.stdout.on('drain', _) } } createuser(never_called_callback); // either creates new user or logs error exists.
also see this article helped me settle things right way.
Comments
Post a Comment