Heroku Node.js application fails to start
Problem
I've been developing my first Node.js application (actually, moving some old code to Node for fun and practice) and am playing with hosting it on Heroku.
I've been able to get the application as it stands running swimmingly locally using foreman, but whenever I deploy the app to Heroku it starts, but fails to serve the queries. I've done some research and can't find anything specific, but it looks to me like a couple of modules haven't been correctly installed by Heroku?
The MySQL database is hosted in Amazon RDS, and I've already followed and rechecked the steps, access rights and security exceptions and there doesn't seem to be an issue.
I'm using the following modules, defined in my package.json:
{
"name": "AppName",
"version": "0.0.1",
"dependencies": {
"express": "2.5.x",
"jade": "0.28.1",
"stylus": "0.32.0",
"mysql": "2.0.0-alpha7",
"string": "1.2.*",
"sanitizer": "0.0.*",
"validator": "0.4.8"
},
"engines": {
"node": "0.8.*",
"npm": "1.*.*"
}
}
Called at the top of my app file:
var express = require('express');
var crypto = require('crypto');
var S = require('string');
var mysql = require('mysql');
var sanitizer = require('sanitizer');
var check = require('validator').check,
sanitize = require('validator').sanitize;
The error message is as follows:
TypeError: Cannot call method 'query' of undefined
at pool.getConnection.app.get.connection.query.res.render.global_title (/app/web.js:40:14)
at callbacks (/app/node_modules/express/lib/router/index.js:272:11)
at param (/app/node_modules/express/lib/router/index.js:246:11)
at pass (/app/node_modules/express/lib/router/index.js:253:5)
at Router._dispatch (/app/node_modules/express/lib/router/index.js:280:5)
at Object.middleware [as handle] (/app/node_modules/express/lib/router/index.js:45:10)
at next (/app/node_modules/express/node_modules/connect/lib/http.js:204:15)
at Object.stylus (/app/node_modules/stylus/lib/middleware.js:181:7)
at next (/app/node_modules/express/node_modules/connect/lib/http.js:204:15)
at Object.methodOverride [as handle] (/app/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js:35:5)
And the segment of code that is failing:
pool.getConnection(function(err, connection) {
app.get('/', function(req, res){
connection.query('QUERY_HERE', function(err, rows, fields) {
if (err) throw console.log(err);
res.render('index', {
global_title: S(site_title).stripTags().s,
title: S(rows[0].title).stripTags().s,
bodytext: sanitize(sanitizer.sanitize(rows[0].content)).xss()
});
connection.end();
});
});
//end connection
});
This is the only error that Heroku gives me in the browser or logs, and it doesn't seem to have any trouble building it.
I'm kind of at a loss here, so hoping someone can point out exactly where I'm being an idiot and get me rolling before I resort to contacting Heroku!
Thanks in advance.
Update:
Using a code change suggested by Pascal Belloncle to capture the error in the logs yields an application error in the browser and the following in the log:
connection.query(QUERY, function(err, row
at Handshake.Sequence.end (/app/node_modules/mysql/lib/protocol/sequences/Sequence.js:66:24)
at Protocol.handleNetworkError (/app/node_modules/mysql/lib/protocol/Protocol.js:230:14)
at Socket.EventEmitter.emit (events.js:126:20)
at Socket._destroy.self.errorEmitted (net.js:328:14)
TypeError: Cannot call method 'query' of undefined
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
at Handshake.Pool.getConnection [as _callback] (/app/node_modules/mysql/lib/Pool.js:35:9)
at Connection._handleNetworkError (/app/node_modules/mysql/lib/Connection.js:145:18)
at /app/web.js:40:15
Still seems to be crashing at the same point with no useful error.
Update 2:
An error message!
2013-02-06T06:32:57+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=GET path=/ host=trash-media.herokuapp.com fwd=31.3.253.10 dyno=web.1 queue=0ms wait=0ms connect=4ms service=21033ms status=503 bytes=0
https://devcenter.heroku.com/articles/error-codes#h13-connection-closed-without-response
Update 3:
After seeing the error message from update 2 and doing some fiddling with the security settings in RDS, this now looks like it is related to the difference in availability zone between where Heroku is hosted (us-west) and where my RDS DB is (eu-west). I've raised it with Heroku support and will close this question with an answer should I get one, and hopefully a working solution or workaround.
Solution
I'm closing this question as the issue now appears to be related to the difference in availability zones in AWS between where the Heroku app is (US) and where the RDS is (EU).
Despite changing the zone as suggested on the RDS developer tools walkthrough, Heroku still cannot interact with my RDS.
The workaround for this is to change security group policies for the RDS database to allow all connections:
0.0.0.0/0
Or move the database to the US availability zone.
Hardly ideal.
I've now been waiting four days for a reply from Heroku support with any other suggestions, so if they come back I will add them to this answer.
Discussion
View additional discussion.