Skip to content

Commit 5cb38f5

Browse files
LinusUbrianc
authored andcommitted
Handle throws in type parsers (brianc#1218)
* Handle throws in type parsers * Fix throw in type parsers test for Node 0.x
1 parent 4101781 commit 5cb38f5

File tree

2 files changed

+125
-1
lines changed

2 files changed

+125
-1
lines changed

lib/query.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,19 @@ Query.prototype.handleRowDescription = function(msg) {
8080
};
8181

8282
Query.prototype.handleDataRow = function(msg) {
83-
var row = this._result.parseRow(msg.fields);
83+
var row;
84+
85+
if (this._canceledDueToError) {
86+
return;
87+
}
88+
89+
try {
90+
row = this._result.parseRow(msg.fields);
91+
} catch (err) {
92+
this._canceledDueToError = err;
93+
return;
94+
}
95+
8496
this.emit('row', row, this._result);
8597
if (this._accumulateRows) {
8698
this._result.addRow(row);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
var helper = require(__dirname + "/test-helper");
2+
var types = require('pg-types')
3+
4+
test('handles throws in type parsers', function() {
5+
var typeParserError = new Error('TEST: Throw in type parsers');
6+
7+
types.setTypeParser('special oid that will throw', function () {
8+
throw typeParserError;
9+
});
10+
11+
test('emits error', function() {
12+
var handled;
13+
var client = helper.client();
14+
var con = client.connection;
15+
var query = client.query('whatever');
16+
17+
handled = con.emit('readyForQuery');
18+
assert.ok(handled, "should have handled ready for query");
19+
20+
con.emit('rowDescription',{
21+
fields: [{
22+
name: 'boom',
23+
dataTypeID: 'special oid that will throw'
24+
}]
25+
});
26+
assert.ok(handled, "should have handled row description");
27+
28+
assert.emits(query, 'error', function(err) {
29+
assert.equal(err, typeParserError);
30+
});
31+
32+
handled = con.emit('dataRow', { fields: ["hi"] });
33+
assert.ok(handled, "should have handled first data row message");
34+
35+
handled = con.emit('commandComplete', { text: 'INSERT 31 1' });
36+
assert.ok(handled, "should have handled command complete");
37+
38+
handled = con.emit('readyForQuery');
39+
assert.ok(handled, "should have handled ready for query");
40+
});
41+
42+
test('calls callback with error', function() {
43+
var handled;
44+
45+
var callbackCalled = 0;
46+
47+
var client = helper.client();
48+
var con = client.connection;
49+
var query = client.query('whatever', assert.calls(function (err) {
50+
callbackCalled += 1;
51+
52+
assert.equal(callbackCalled, 1);
53+
assert.equal(err, typeParserError);
54+
}));
55+
56+
handled = con.emit('readyForQuery');
57+
assert.ok(handled, "should have handled ready for query");
58+
59+
handled = con.emit('rowDescription',{
60+
fields: [{
61+
name: 'boom',
62+
dataTypeID: 'special oid that will throw'
63+
}]
64+
});
65+
assert.ok(handled, "should have handled row description");
66+
67+
handled = con.emit('dataRow', { fields: ["hi"] });
68+
assert.ok(handled, "should have handled first data row message");
69+
70+
handled = con.emit('dataRow', { fields: ["hi"] });
71+
assert.ok(handled, "should have handled second data row message");
72+
73+
con.emit('commandComplete', { text: 'INSERT 31 1' });
74+
assert.ok(handled, "should have handled command complete");
75+
76+
handled = con.emit('readyForQuery');
77+
assert.ok(handled, "should have handled ready for query");
78+
});
79+
80+
test('rejects promise with error', function() {
81+
var handled;
82+
var client = helper.client();
83+
var con = client.connection;
84+
var query = client.query('whatever');
85+
var queryPromise = query.promise();
86+
87+
handled = con.emit('readyForQuery');
88+
assert.ok(handled, "should have handled ready for query");
89+
90+
handled = con.emit('rowDescription',{
91+
fields: [{
92+
name: 'boom',
93+
dataTypeID: 'special oid that will throw'
94+
}]
95+
});
96+
assert.ok(handled, "should have handled row description");
97+
98+
handled = con.emit('dataRow', { fields: ["hi"] });
99+
assert.ok(handled, "should have handled first data row message");
100+
101+
handled = con.emit('commandComplete', { text: 'INSERT 31 1' });
102+
assert.ok(handled, "should have handled command complete");
103+
104+
handled = con.emit('readyForQuery');
105+
assert.ok(handled, "should have handled ready for query");
106+
107+
queryPromise.catch(assert.calls(function (err) {
108+
assert.equal(err, typeParserError);
109+
}));
110+
});
111+
112+
});

0 commit comments

Comments
 (0)