diff --git a/Readme.md b/Readme.md index db368b327..9e026d494 100644 --- a/Readme.md +++ b/Readme.md @@ -158,6 +158,9 @@ issue [#501](https://github.com/felixge/node-mysql/issues/501). (Default: `'fals * `dateStrings`: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then inflated into JavaScript Date objects. (Default: `false`) * `debug`: Prints protocol details to stdout. (Default: `false`) +* `trace`: Generates stack traces on `Error` to include call site of library + entrance ("long stack traces"). Slight performance penalty for most calls. + (Default: `true`) * `multipleStatements`: Allow multiple mysql statements per query. Be careful with this, it exposes you to SQL injection attacks. (Default: `false`) * `flags`: List of connection flags to use other than the default ones. It is diff --git a/lib/ConnectionConfig.js b/lib/ConnectionConfig.js index cae16443b..d6e0a5168 100644 --- a/lib/ConnectionConfig.js +++ b/lib/ConnectionConfig.js @@ -20,6 +20,7 @@ function ConnectionConfig(options) { this.bigNumberStrings = options.bigNumberStrings || false; this.dateStrings = options.dateStrings || false; this.debug = options.debug; + this.trace = options.trace !== false; this.stringifyObjects = options.stringifyObjects || false; this.timezone = options.timezone || 'local'; this.flags = options.flags || ''; diff --git a/lib/protocol/Protocol.js b/lib/protocol/Protocol.js index 7e350d830..a087cc7d6 100644 --- a/lib/protocol/Protocol.js +++ b/lib/protocol/Protocol.js @@ -105,6 +105,11 @@ Protocol.prototype._enqueue = function(sequence) { return sequence; } + if (this._config.trace) { + // Long stack trace support + sequence._callSite = new Error; + } + this._queue.push(sequence); var self = this; diff --git a/lib/protocol/sequences/Sequence.js b/lib/protocol/sequences/Sequence.js index 3ece0f524..dc4988eb0 100644 --- a/lib/protocol/sequences/Sequence.js +++ b/lib/protocol/sequences/Sequence.js @@ -9,10 +9,8 @@ function Sequence(callback) { EventEmitter.call(this); this._callback = callback; + this._callSite = null; this._ended = false; - - // Experimental: Long stack trace support - this._callSite = new Error; } Sequence.determinePacket = function(byte) { @@ -38,7 +36,12 @@ Sequence.prototype._packetToError = function(packet) { }; Sequence.prototype._addLongStackTrace = function(err) { + if (!this._callSite) { + return; + } + var delimiter = '\n --------------------\n' ; + if (err.stack.indexOf(delimiter) > -1) { return; } @@ -62,7 +65,7 @@ Sequence.prototype.end = function(err) { // causes a cyclic reference that the GC does not detect properly, but I was // unable to produce a standalone version of this leak. This would be a great // challenge for somebody interested in difficult problems : )! - delete this._callSite; + this._callSite = null; // try...finally for exception safety try { diff --git a/test/integration/connection/test-long-stack-traces-disabled.js b/test/integration/connection/test-long-stack-traces-disabled.js new file mode 100644 index 000000000..b4d2e53fe --- /dev/null +++ b/test/integration/connection/test-long-stack-traces-disabled.js @@ -0,0 +1,14 @@ +var common = require('../../common'); +var connection = common.createConnection({trace: false}); +var assert = require('assert'); + +var err; +connection.query('invalid sql', function(_err) { + err = _err; +}); + +connection.end(); + +process.on('exit', function() { + assert.ok(err.stack.indexOf(__filename) < 0); +}); diff --git a/test/integration/connection/test-long-stack-traces.js b/test/integration/connection/test-long-stack-traces.js index def47fc90..7cc5029ae 100644 --- a/test/integration/connection/test-long-stack-traces.js +++ b/test/integration/connection/test-long-stack-traces.js @@ -1,5 +1,3 @@ -// Experimental: https://github.com/felixge/node-mysql/issues/198 - var common = require('../../common'); var connection = common.createConnection(); var assert = require('assert');