Make throws in query error callback not break client

If you receive an error while running a query and in user's callback
they throw an exception it can disrupt the internal query queue
and prevent a client from ever cleaning up properly
This commit is contained in:
bmc 2013-04-19 09:25:53 -05:00
parent 9b1c4facc2
commit 56a5903a02
3 changed files with 33 additions and 18 deletions

View File

@ -173,8 +173,9 @@ Client.prototype.connect = function(callback) {
if(self.activeQuery.isPreparedStatement) {
con.sync();
}
self.activeQuery.handleError(error);
var activeQuery = self.activeQuery;
self.activeQuery = null;
activeQuery.handleError(error);
}
});

View File

@ -58,8 +58,10 @@ NativeQuery.prototype.handleError = function(error) {
this._canceledDueToError = false;
}
if(this.callback) {
this.callback(error);
var cb = this.callback;
//remove callback to prevent double call on readyForQuery
this.callback = null;
cb(error);
} else {
this.emit('error', error);
}

View File

@ -1,22 +1,34 @@
var helper = require(__dirname + '/test-helper');
var util = require('util');
test('error during query execution', function() {
var client = new Client(helper.args);
process.removeAllListeners('uncaughtException');
assert.emits(process, 'uncaughtException', function() {
assert.equal(client.activeQuery, null, 'should remove active query even if error happens in callback');
client.query('SELECT * FROM blah', assert.success(function(result) {
assert.equal(result.rows.length, 1);
client.end();
}));
});
client.connect(assert.success(function() {
client.query('CREATE TEMP TABLE "blah"(data text)', assert.success(function() {
var q = client.query('INSERT INTO blah(data) VALUES($1)', ['yo'], assert.success(function() {
assert.emits(client, 'drain');
throw new Error('WHOOOAAAHH!!');
var withQuery = function(text, resultLength, cb) {
test('error during query execution', function() {
var client = new Client(helper.args);
process.removeAllListeners('uncaughtException');
assert.emits(process, 'uncaughtException', function() {
console.log('got uncaught exception')
assert.equal(client.activeQuery, null, 'should remove active query even if error happens in callback');
client.query('SELECT * FROM blah', assert.success(function(result) {
assert.equal(result.rows.length, resultLength);
client.end();
cb();
}));
});
client.connect(assert.success(function() {
client.query('CREATE TEMP TABLE "blah"(data text)', assert.success(function() {
var q = client.query(text, ['yo'], assert.calls(function() {
assert.emits(client, 'drain');
throw new Error('WHOOOAAAHH!!');
}));
}));
}));
}));
});
}
//test with good query so our callback is called
//as a successful callback
withQuery('INSERT INTO blah(data) VALUES($1)', 1, function() {
//test with an error query so our callback is called with an error
withQuery('INSERT INTO asldkfjlaskfj eoooeoriiri', 0, function() {
});
});