Skip to content

Commit 5013c07

Browse files
committed
Fix edge cases constructing long stack traces
fixes #1387
1 parent ef55076 commit 5013c07

File tree

5 files changed

+84
-14
lines changed

5 files changed

+84
-14
lines changed

Changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ you spot any mistakes.
88

99
* Add `POOL_CLOSED` code to "Pool is closed." error
1010
* Add `POOL_CONNLIMIT` code to "No connections available." error #1332
11+
* Fix edge cases constructing long stack traces #1387
1112
* Fix Query stream to emit close after ending #1349 #1350
1213
* Fix type cast for BIGINT columns when number is negative #1376
1314
* Performance improvements for array/object escaping in SqlString #1331

lib/protocol/sequences/Sequence.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ var ErrorConstants = require('../constants/errors');
66
var listenerCount = EventEmitter.listenerCount
77
|| function(emitter, type){ return emitter.listeners(type).length; };
88

9+
var LONG_STACK_DELIMITER = '\n --------------------\n';
10+
911
module.exports = Sequence;
1012
Util.inherits(Sequence, EventEmitter);
1113
function Sequence(options, callback) {
@@ -54,20 +56,6 @@ Sequence.prototype._packetToError = function(packet) {
5456
return err;
5557
};
5658

57-
Sequence.prototype._addLongStackTrace = function _addLongStackTrace(err) {
58-
if (!this._callSite || !this._callSite.stack) {
59-
return;
60-
}
61-
62-
var delimiter = '\n --------------------\n';
63-
64-
if (err.stack.indexOf(delimiter) > -1) {
65-
return;
66-
}
67-
68-
err.stack += delimiter + this._callSite.stack.replace(/.+\n/, '');
69-
};
70-
7159
Sequence.prototype.end = function(err) {
7260
if (this._ended) {
7361
return;
@@ -113,6 +101,27 @@ Sequence.prototype['ErrorPacket'] = function(packet) {
113101
// Implemented by child classes
114102
Sequence.prototype.start = function() {};
115103

104+
Sequence.prototype._addLongStackTrace = function _addLongStackTrace(err) {
105+
var callSiteStack = this._callSite && this._callSite.stack;
106+
107+
if (!callSiteStack || typeof callSiteStack !== 'string') {
108+
// No recorded call site
109+
return;
110+
}
111+
112+
if (err.stack.indexOf(LONG_STACK_DELIMITER) !== -1) {
113+
// Error stack already looks long
114+
return;
115+
}
116+
117+
var index = callSiteStack.indexOf('\n');
118+
119+
if (index !== -1) {
120+
// Append recorded call site
121+
err.stack += LONG_STACK_DELIMITER + callSiteStack.substr(index + 1);
122+
}
123+
};
124+
116125
Sequence.prototype._onTimeout = function _onTimeout() {
117126
this.emit('timeout');
118127
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var assert = require('assert');
2+
var common = require('../../common');
3+
var connection = common.createConnection({port: common.fakeServerPort});
4+
5+
var server = common.createFakeServer();
6+
7+
server.listen(common.fakeServerPort, function (err) {
8+
assert.ifError(err);
9+
10+
// Common mistake to leave in code
11+
Error.prepareStackTrace = function (err, stack) {
12+
return stack;
13+
};
14+
15+
connection.query('INVALID SQL', function (err) {
16+
assert.ok(err, 'got error');
17+
assert.ok(typeof err.stack !== 'string', 'error stack is not a string');
18+
19+
connection.destroy();
20+
server.destroy();
21+
});
22+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var assert = require('assert');
2+
var common = require('../../common');
3+
var connection = common.createConnection({port: common.fakeServerPort});
4+
5+
var server = common.createFakeServer();
6+
7+
server.listen(common.fakeServerPort, function (err) {
8+
assert.ifError(err);
9+
10+
Error.stackTraceLimit = 0;
11+
12+
connection.query('INVALID SQL', function (err) {
13+
assert.ok(err, 'got error');
14+
assert.ok(!err.stack || err.stack.indexOf('\n --------------------\n') === -1,
15+
'error stack does not have delimiter');
16+
17+
connection.destroy();
18+
server.destroy();
19+
});
20+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var assert = require('assert');
2+
var common = require('../../common');
3+
var connection = common.createConnection({port: common.fakeServerPort});
4+
5+
var server = common.createFakeServer();
6+
7+
server.listen(common.fakeServerPort, function (err) {
8+
assert.ifError(err);
9+
10+
connection.query('INVALID SQL', function (err) {
11+
assert.ok(err, 'got error');
12+
assert.ok(typeof err.stack === 'string', 'error stack is string');
13+
assert.ok(err.stack.indexOf('\n --------------------\n') !== -1, 'error stack has delimiter');
14+
15+
connection.destroy();
16+
server.destroy();
17+
});
18+
});

0 commit comments

Comments
 (0)