//------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- if (this.WScript && this.WScript.LoadScriptFile) { this.WScript.LoadScriptFile("LongCallStackThrow.js"); } Dump("-- Error.stackTraceLimit property descriptor"); var desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit"); for(var p in desc) { Dump(p + ": " + desc[p]); } Dump(""); function testLongCallStack(limit, noHeader) { if (limit !== undefined) { Error.stackTraceLimit = 7; // if next assignment is rejected Error.stackTraceLimit = limit; } if (!noHeader) { Dump("-- Error.stackTraceLimit: " + String(Error.stackTraceLimit)); } runtest(30); Dump(""); } testLongCallStack(); testLongCallStack(4); testLongCallStack(Infinity); testLongCallStack(1); testLongCallStack(20); testLongCallStack(5.1); testLongCallStack(-1); testLongCallStack(-3.2); testLongCallStack(-Infinity); testLongCallStack(0); testLongCallStack(+0); testLongCallStack(-0); testLongCallStack(Number.NaN); testLongCallStack("not a number"); testLongCallStack(new Object()); Error.stackTraceLimit = 8; Dump("-- preset Error.stackTraceLimit: " + Error.stackTraceLimit); Dump(""); Dump("--Reconfigure to a getter"); Object.defineProperty(Error, "stackTraceLimit", { get: function () { Dump("** Custom stackTraceLimit getter Called, return 3"); return 3; }, configurable: true }); testLongCallStack(undefined, true); Dump("--Delete it"); delete Error.stackTraceLimit; testLongCallStack(); Dump("--Available on prototype"); Function.prototype.stackTraceLimit = 2; testLongCallStack(); Dump("--Set to data property again"); Error.stackTraceLimit = 5; testLongCallStack(); Dump("--Throw in getter"); Object.defineProperty(Error, "stackTraceLimit", { get: function () { Dump("** Custom stackTraceLimit getter Called, throw"); throw "My error in custom stackTraceLimit getter"; }, configurable: true }); testLongCallStack(undefined, true); Dump("--Throw new Error() in getter"); Object.defineProperty(Error, "stackTraceLimit", { get: function () { throw new Error("My error in custom stackTraceLimit getter"); }, configurable: true }); testLongCallStack(undefined, true); Dump("--Throw new Error() in getter for a number of times"); var throwErrorCount = 4; Object.defineProperty(Error, "stackTraceLimit", { get: function () { if (throwErrorCount-- > 0) { throw new Error("My error in custom stackTraceLimit getter"); } else { return -1; } }, configurable: true }); testLongCallStack(undefined, true); // Some more tests of different types (appending here to avoid affecting above tests' baseline) delete Error.stackTraceLimit; var moreTests = [ null, undefined, true, false, new Boolean(true), new Boolean(false), "4", new String("5"), new Number(6), new Number(Number.NaN), new Number(Number.Infinity), new Number(-2), [], [1, 2, 3], {}, { valueOf: function () { return 2; }, toString: function () { return "valueOf override"; } }, { valueOf: function () { throw new Error("evil"); }, toString: function () { return "valueOf override throw"; } }, ]; moreTests.forEach(function (x) { if (x === undefined) { Error.stackTraceLimit = undefined; } testLongCallStack(x); });