Skip to content

Commit 654a058

Browse files
committed
callback in nextTick so it can't corrupt client
1 parent 07fd762 commit 654a058

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

lib/query.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,17 @@ Query.prototype.handleReadyForQuery = function() {
9595
if(this._canceledDueToError) {
9696
return this.handleError(this._canceledDueToError);
9797
}
98+
9899
if(this.callback) {
99-
this.callback(null, this._result);
100+
var that = {
101+
callback: this.callback,
102+
result: this._result
103+
};
104+
process.nextTick(function () {
105+
that.callback(null, that.result);
106+
});
100107
}
108+
101109
this.emit('end', this._result);
102110
};
103111

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
var args = require(__dirname + '/../cli');
2+
var pg = require(__dirname + "/../../lib");
3+
4+
process.on('uncaughtException', function(err) {
5+
console.log(err.message);
6+
});
7+
8+
var query = {
9+
text: 'select * from person where id = $1'
10+
, values: [1]
11+
};
12+
var queries = 0;
13+
14+
pg.connect(args, function(err, client) {
15+
setTimeout(function() {
16+
throw new Error('#1');
17+
}, 500);
18+
19+
setTimeout(function() {
20+
client.query(query, function(err, result) {
21+
console.log('ran first query');
22+
queries++;
23+
throw new Error('#2');
24+
});
25+
}, 1000);
26+
27+
setTimeout(function() {
28+
client.query(query, function(err, result) {
29+
console.log('ran second query');
30+
queries++;
31+
});
32+
}, 1500);
33+
34+
setTimeout(function() {
35+
client.end();
36+
if (queries !== 2) {
37+
throw new Error('test failed!');
38+
}
39+
}, 2000);
40+
41+
setTimeout(function() {
42+
process.exit();
43+
}, 2500);
44+
45+
});

test/test-helper.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ var Connection = require(__dirname + '/../lib/connection');
1010
Client = require(__dirname + '/../lib').Client;
1111

1212
process.on('uncaughtException', function(d) {
13+
// quietly absorb fake errors
14+
if (d.message === 'Fake Error') return;
15+
1316
if ('stack' in d && 'message' in d) {
1417
console.log("Message: " + d.message);
1518
console.log(d.stack);
@@ -187,6 +190,9 @@ process.on('exit', function() {
187190
})
188191

189192
process.on('uncaughtException', function(err) {
193+
// quietly absorb fake errors
194+
if (err.message === 'Fake Error') return;
195+
190196
console.error("\n %s", err.stack || err.toString())
191197
//causes xargs to abort right away
192198
process.exit(255);

test/unit/client/simple-query-tests.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,53 @@ test('executing query', function() {
121121
});
122122
});
123123

124+
test('handleReadyForQuery emits \'end\' even if callback throws an exception', function() {
125+
var client = helper.client();
126+
var query = client.query('whatever');
127+
128+
query.callback = function() {
129+
throw new Error('Fake Error');
130+
};
131+
assert.emits(query, 'end');
132+
133+
try {
134+
query.handleReadyForQuery();
135+
}
136+
catch (e) {}
137+
});
138+
139+
test('handleError emits \'end\' even if callback throws an exception', function() {
140+
var client = helper.client();
141+
var query = client.query('whatever');
142+
143+
query.callback = function() {
144+
throw new Error('Fake Error');
145+
};
146+
assert.emits(query, 'end');
147+
148+
try {
149+
query.handleReadyForQuery();
150+
}
151+
catch (e) {}
152+
});
153+
154+
test('client \'readyForQuery\' handler sets readyForQuery to true even if callback throws an exception', function() {
155+
var client = helper.client();
156+
var query = client.query('whatever');
157+
158+
query.callback = function() {
159+
throw new Error('Fake Error');
160+
};
161+
client.activeQuery = query;
162+
client.readyForQuery = false;
163+
client._pulseQueryQueue = function() {};
164+
try {
165+
client.connection.emit('readyForQuery');
166+
}
167+
catch (e) {}
168+
assert.equal(true, client.readyForQuery);
169+
});
170+
124171
});
125172

126173
});

0 commit comments

Comments
 (0)