4

I am trying to get my node.js express app to connect to a MongoLab database on Heroku using Mongoose. I have used app.configure to set my database URI to my MongoLab URI on production, and as you can see in the Heroku Logs it is definitely setting dbURI to the MongoLab URI. I have definitely set my NODE_ENV to production. What is my issue?

app.js:

var express = require('express');
var mongoose = require('mongoose')
  , dbURI = 'localhost';
var app = express();

app.configure('production', function () {
    console.log("production!");
    dbURI = 'mongodb://brad.ross.35:Brad1234@ds031347.mongolab.com:31347/heroku_app6861425';
    console.log(dbURI);
});

mongoose.connect(dbURI, 'test');
mongoose.connection.on('error', console.error.bind(console, 'connection error:'));

var postSchema = new mongoose.Schema({
    body: String
});

var Post = mongoose.model('Post', postSchema);

app.configure(function () {
    //app.use(express.logger());
    app.use(express.bodyParser());
    app.use(express.static(__dirname + '/static'));
});

app.set('views', __dirname + '/views');
app.set('view engine','jade');

app.get('/', function(request, response) {
    response.render('index');
});

app.post('/result', function(request, response) {
    var post = new Post({body: request.body.text});
    post.save(function (err) {
        if (err) {
            console.log("error!");
        } else {
            console.log("saved!");
        }
    });

    Post.find(function (err, posts) {
        if (!err) {
            console.log("found!");
            console.log(posts);
            response.render('result', {posts: posts});
        } else {
            console.log("error!");
            response.render('result', {posts: []});
        }
    });
});

app.get('/result', function (request, response) {
    Post.find(function (err, posts) {
        if (!err) {
            console.log("found!");
            console.log(posts);
            response.render('result', {posts: posts});
        } else {
            console.log("error!");
            response.render('result', {posts: []});
        }
    });
});

app.listen(process.env.PORT || 5000);

Heroku Logs:

2012-08-21T16:52:21+00:00 heroku[web.1]: State changed from crashed to starting
2012-08-21T16:52:22+00:00 heroku[slugc]: Slug compilation finished
2012-08-21T16:52:23+00:00 heroku[web.1]: Starting process with command `node app.js`
2012-08-21T16:52:24+00:00 app[web.1]: production!
2012-08-21T16:52:24+00:00 app[web.1]: mongodb://brad.ross.35:PASSWORD@ds031347.mongolab.com:31347/heroku_app6861425
2012-08-21T16:52:24+00:00 app[web.1]: connection error: [Error: failed to connect to [ds031347.mongolab.com:31347/heroku_app6861425:27017]]
2012-08-21T16:52:25+00:00 heroku[web.1]: State changed from starting to up
Brad Ross
  • 451
  • 8
  • 26
  • 1
    Please include the code in your post, not just links. – Jamund Ferguson Aug 21 '12 at 17:01
  • I get the same error when connecting over command line... `mongo -u brad.ross.35 -p Brad1234 ds031347.mongolab.com:31347/heroku_app6861425 ` but maybe your password isn't really that. – Jamund Ferguson Aug 21 '12 at 17:09
  • I'm having the same issue, except I'm getting this error: "Error: database names cannot contain the character '.'" I've tried a lot and haven't gotten this to work. I'm working with mongolabs support now. Have you contacted them? – Miles Oct 06 '12 at 21:47

2 Answers2

3

When passing a URI there is no need to pass the database name separately (which confuses mongoose).

Just do

var uri = 'mongodb://brad.ross.35:Brad1234@ds031347.mongolab.com:31347/heroku_app6861425'
mongoose.connect(uri)

to use the test db, change your uri:

var uri = 'mongodb://brad.ross.35:Brad1234@ds031347.mongolab.com:31347/test'
aaronheckmann
  • 10,625
  • 2
  • 40
  • 30
  • It goes through, but when I try to go to the /result page it just gives me an "internal server error" and logs this: Stopping all processes with SIGTERM 2012-08-22T00:27:34+00:00 heroku[web.1]: State changed from starting to up 2012-08-22T00:27:35+00:00 heroku[web.1]: Process exited with status 1 – Brad Ross Aug 22 '12 at 00:41
0

I haven't worked with Mongoose but when I had connection problems with MongoLab in the past it was due to a race condition caused by connecting to the db and client code which assumes the connect. Typically the solution is to bind to the open event or provide a callback which is invoked by the underlying driver before resuming the start up that requires a connection. This is what I do with Mongoskin and I never have an issue.

hth mike

SonOfNun
  • 957
  • 7
  • 11
  • 1
    I don't quite understand. You mean to have a callback that executes before the rest of the app continues? Isn't that not really possible in Node? Can you be a little bit more specific and add an example maybe? – Brad Ross Aug 22 '12 at 04:52
  • You mean nest everything else inside a callback on the `mongoose.connect` function? – Brad Ross Aug 22 '12 at 14:12
  • Hi Brad. I had a look at mongoose docs and it fires an `open` event on the connection you receive. So just like you are binding to the 'error' event in your code you can bind to the 'open' event. Wrap your init code in a function and pass that into your `open` callback. //app.js var startApp = function() { app.configure(...) // other init tasks } mongoose.connection.on 'open', startApp – SonOfNun Aug 22 '12 at 14:18
  • I tried doing so, and it seemed to work, but I still got an `Internal Server Error` when connecting to the `/result` page... – Brad Ross Aug 22 '12 at 14:21
  • Can you show how you are applying your init code to the 'open' event? I edited my earlier answer to this too. – SonOfNun Aug 22 '12 at 14:49
  • Due to the restrictive character limit, here it is: http://d.pr/f/He8V. One thing to note is check out this link: http://stackoverflow.com/questions/7575664/node-js-connecting-to-mongodb-using-mongohq-on-heroku. I think it is some kind of router issue. Also, I think I messed up with my database. I am trying to connect to my old one that I deleted, but I should try to connect to the new one. – Brad Ross Aug 22 '12 at 15:20
  • You might want to try binding to the `open` event like I suggested. It isn't clear from the mongoose docs whether the callback is supported like you are doing in your app.js or whether the arguments are correct. Like I said, though, I am not a mongoose guy. – SonOfNun Aug 22 '12 at 15:45
  • bind as in... callback on the open event? I am kind of new to node. – Brad Ross Aug 22 '12 at 15:54
  • Yes, sorry. Nodejs uses 'emit/on' for event publication/subscriptions. Other libs use 'bind/trigger' and the list goes on... So you can: mongoose.connect myUrl; mongoose.connection.on 'open', initAppFn – SonOfNun Aug 22 '12 at 18:23
  • Ok. So I did that, and it connected at first, but then it ended the process with `process ended with status 1`. I could still run requests, but it wouldn't connect to the database – Brad Ross Aug 22 '12 at 19:30