From 87b644e4d6ce9c1e22a59fe50ce1989f6f2498b6 Mon Sep 17 00:00:00 2001 From: Stefan-Gabriel Muscalu Date: Thu, 26 Oct 2017 13:00:55 +0300 Subject: [PATCH 1/2] Add: [Result] integrate stack traces outside of driver's scope --- src/v1/result.js | 2 ++ test/v1/result.test.js | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/v1/result.js b/src/v1/result.js index d3bb94c14..cc6cb780b 100644 --- a/src/v1/result.js +++ b/src/v1/result.js @@ -45,6 +45,7 @@ class Result { * @param {ConnectionHolder} connectionHolder - to be notified when result is either fully consumed or error happened. */ constructor(streamObserver, statement, parameters, metaSupplier, connectionHolder) { + this._stack = (new Error('')).stack.substr(6); // we don't need the 'Error\n' part this._streamObserver = streamObserver; this._p = null; this._statement = statement; @@ -137,6 +138,7 @@ class Result { // notify connection holder that the used connection is not needed any more because error happened // and result can't bee consumed any further; call the original onError callback after that self._connectionHolder.releaseConnection().then(() => { + error.stack = error.stack + '\n' + this._stack; onErrorOriginal.call(observer, error); }); }; diff --git a/test/v1/result.test.js b/test/v1/result.test.js index 4bc601756..efe3feef0 100644 --- a/test/v1/result.test.js +++ b/test/v1/result.test.js @@ -72,4 +72,27 @@ describe('result stream', () => { } }); }); + + it('should have a stack trace that contains code outside the driver calls', done => { + // Given + const fn_a = cb => fn_b(cb); + const fn_b = cb => fn_c(cb); + const fn_c = cb => session.run('RETURN 1/0 AS x').catch(cb); + + // When + fn_a(err => { + const stack = err.stack; + + // Then + const contains_fn_a = /at fn_a \(.*?\/result.test.js:\d+:\d+\)/.test(stack); + const contains_fn_b = /at fn_b \(.*?\/result.test.js:\d+:\d+\)/.test(stack); + const contains_fn_c = /at fn_c \(.*?\/result.test.js:\d+:\d+\)/.test(stack); + + expect(contains_fn_a).toBeTruthy(); + expect(contains_fn_b).toBeTruthy(); + expect(contains_fn_c).toBeTruthy(); + + done(); + }); + }); }); From 04f1248086ebae0961037a1cc3df0ac8c3a3fd13 Mon Sep 17 00:00:00 2001 From: Stefan-Gabriel Muscalu Date: Mon, 6 Nov 2017 15:24:43 +0200 Subject: [PATCH 2/2] Update: [Result] Keep only the caller's stack trace, discard the old one --- src/v1/result.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/v1/result.js b/src/v1/result.js index cc6cb780b..7b8b0e938 100644 --- a/src/v1/result.js +++ b/src/v1/result.js @@ -138,7 +138,9 @@ class Result { // notify connection holder that the used connection is not needed any more because error happened // and result can't bee consumed any further; call the original onError callback after that self._connectionHolder.releaseConnection().then(() => { - error.stack = error.stack + '\n' + this._stack; + // Error.prototype.toString() concatenates error.name and error.message nicely + // then we add the rest of the stack trace + error.stack = error.toString() + '\n' + this._stack; onErrorOriginal.call(observer, error); }); };