diff --git a/packages/core/src/util/stackTrace.js b/packages/core/src/util/stackTrace.js index aa4d9fda04..218735856f 100644 --- a/packages/core/src/util/stackTrace.js +++ b/packages/core/src/util/stackTrace.js @@ -37,11 +37,17 @@ exports.captureStackTrace = function captureStackTrace(length, referenceFunction // drawback is that it might show too much, but that's better than not having any stack trace at all. Error.captureStackTrace(stackTraceTarget); } - const stack = stackTraceTarget.stack; + + let stack = stackTraceTarget.stack; + + if (!Array.isArray(stack)) { + stack = []; + } + Error.stackTraceLimit = originalLimit; Error.prepareStackTrace = originalPrepareStackTrace; - if (drop > 0) { + if (drop > 0 && stack.length >= drop) { stack.splice(0, drop); } return stack; diff --git a/packages/core/test/util/stackTrace_test.js b/packages/core/test/util/stackTrace_test.js index c4cf4feffe..68cc0727c1 100644 --- a/packages/core/test/util/stackTrace_test.js +++ b/packages/core/test/util/stackTrace_test.js @@ -50,4 +50,33 @@ describe('util/stackTrace', () => { expect(stack[1].m).to.equal('c'); expect(stack).to.have.lengthOf(2); }); + + it('must not capture stack type string', () => { + let stack; + + (function a() { + const stackTraceTarget = { stack: 'this is not an array' }; + const orig = Error.captureStackTrace; + Error.captureStackTrace = target => { + Object.assign(target, stackTraceTarget); + }; + + stack = stackTrace.captureStackTrace(2, a); + Error.captureStackTrace = orig; + })(); + + expect(stack.length).to.equal(0); + }); + + it('must capture stack length < drop', () => { + const stackTraceTarget = { stack: new Array(5) }; + const orig = Error.captureStackTrace; + Error.captureStackTrace = target => { + Object.assign(target, stackTraceTarget); + }; + + const stack = stackTrace.captureStackTrace(2, this, 10); + Error.captureStackTrace = orig; + expect(stack.length).to.equal(5); + }); });