react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / request / node_modules / har-validator / node_modules / bluebird / js / main / captured_trace.js
81160 views"use strict";1module.exports = function() {2var async = require("./async.js");3var util = require("./util.js");4var bluebirdFramePattern =5/[\\\/]bluebird[\\\/]js[\\\/](main|debug|zalgo|instrumented)/;6var stackFramePattern = null;7var formatStack = null;8var indentStackFrames = false;9var warn;1011function CapturedTrace(parent) {12this._parent = parent;13var length = this._length = 1 + (parent === undefined ? 0 : parent._length);14captureStackTrace(this, CapturedTrace);15if (length > 32) this.uncycle();16}17util.inherits(CapturedTrace, Error);1819CapturedTrace.prototype.uncycle = function() {20var length = this._length;21if (length < 2) return;22var nodes = [];23var stackToIndex = {};2425for (var i = 0, node = this; node !== undefined; ++i) {26nodes.push(node);27node = node._parent;28}29length = this._length = i;30for (var i = length - 1; i >= 0; --i) {31var stack = nodes[i].stack;32if (stackToIndex[stack] === undefined) {33stackToIndex[stack] = i;34}35}36for (var i = 0; i < length; ++i) {37var currentStack = nodes[i].stack;38var index = stackToIndex[currentStack];39if (index !== undefined && index !== i) {40if (index > 0) {41nodes[index - 1]._parent = undefined;42nodes[index - 1]._length = 1;43}44nodes[i]._parent = undefined;45nodes[i]._length = 1;46var cycleEdgeNode = i > 0 ? nodes[i - 1] : this;4748if (index < length - 1) {49cycleEdgeNode._parent = nodes[index + 1];50cycleEdgeNode._parent.uncycle();51cycleEdgeNode._length =52cycleEdgeNode._parent._length + 1;53} else {54cycleEdgeNode._parent = undefined;55cycleEdgeNode._length = 1;56}57var currentChildLength = cycleEdgeNode._length + 1;58for (var j = i - 2; j >= 0; --j) {59nodes[j]._length = currentChildLength;60currentChildLength++;61}62return;63}64}65};6667CapturedTrace.prototype.parent = function() {68return this._parent;69};7071CapturedTrace.prototype.hasParent = function() {72return this._parent !== undefined;73};7475CapturedTrace.prototype.attachExtraTrace = function(error) {76if (error.__stackCleaned__) return;77this.uncycle();78var parsed = CapturedTrace.parseStackAndMessage(error);79var message = parsed.message;80var stacks = [parsed.stack];8182var trace = this;83while (trace !== undefined) {84stacks.push(cleanStack(trace.stack.split("\n")));85trace = trace._parent;86}87removeCommonRoots(stacks);88removeDuplicateOrEmptyJumps(stacks);89util.notEnumerableProp(error, "stack", reconstructStack(message, stacks));90util.notEnumerableProp(error, "__stackCleaned__", true);91};9293function reconstructStack(message, stacks) {94for (var i = 0; i < stacks.length - 1; ++i) {95stacks[i].push("From previous event:");96stacks[i] = stacks[i].join("\n");97}98if (i < stacks.length) {99stacks[i] = stacks[i].join("\n");100}101return message + "\n" + stacks.join("\n");102}103104function removeDuplicateOrEmptyJumps(stacks) {105for (var i = 0; i < stacks.length; ++i) {106if (stacks[i].length === 0 ||107((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) {108stacks.splice(i, 1);109i--;110}111}112}113114function removeCommonRoots(stacks) {115var current = stacks[0];116for (var i = 1; i < stacks.length; ++i) {117var prev = stacks[i];118var currentLastIndex = current.length - 1;119var currentLastLine = current[currentLastIndex];120var commonRootMeetPoint = -1;121122for (var j = prev.length - 1; j >= 0; --j) {123if (prev[j] === currentLastLine) {124commonRootMeetPoint = j;125break;126}127}128129for (var j = commonRootMeetPoint; j >= 0; --j) {130var line = prev[j];131if (current[currentLastIndex] === line) {132current.pop();133currentLastIndex--;134} else {135break;136}137}138current = prev;139}140}141142function cleanStack(stack) {143var ret = [];144for (var i = 0; i < stack.length; ++i) {145var line = stack[i];146var isTraceLine = stackFramePattern.test(line) ||147" (No stack trace)" === line;148var isInternalFrame = isTraceLine && shouldIgnore(line);149if (isTraceLine && !isInternalFrame) {150if (indentStackFrames && line.charAt(0) !== " ") {151line = " " + line;152}153ret.push(line);154}155}156return ret;157}158159function stackFramesAsArray(error) {160var stack = error.stack.replace(/\s+$/g, "").split("\n");161for (var i = 0; i < stack.length; ++i) {162var line = stack[i];163if (" (No stack trace)" === line || stackFramePattern.test(line)) {164break;165}166}167if (i > 0) {168stack = stack.slice(i);169}170return stack;171}172173CapturedTrace.parseStackAndMessage = function(error) {174var stack = error.stack;175var message = error.toString();176stack = typeof stack === "string" && stack.length > 0177? stackFramesAsArray(error) : [" (No stack trace)"];178return {179message: message,180stack: cleanStack(stack)181};182};183184CapturedTrace.formatAndLogError = function(error, title) {185if (typeof console !== "undefined") {186var message;187if (typeof error === "object" || typeof error === "function") {188var stack = error.stack;189message = title + formatStack(stack, error);190} else {191message = title + String(error);192}193if (typeof warn === "function") {194warn(message);195} else if (typeof console.log === "function" ||196typeof console.log === "object") {197console.log(message);198}199}200};201202CapturedTrace.unhandledRejection = function (reason) {203CapturedTrace.formatAndLogError(reason, "^--- With additional stack trace: ");204};205206CapturedTrace.isSupported = function () {207return typeof captureStackTrace === "function";208};209210CapturedTrace.fireRejectionEvent =211function(name, localHandler, reason, promise) {212var localEventFired = false;213try {214if (typeof localHandler === "function") {215localEventFired = true;216if (name === "rejectionHandled") {217localHandler(promise);218} else {219localHandler(reason, promise);220}221}222} catch (e) {223async.throwLater(e);224}225226var globalEventFired = false;227try {228globalEventFired = fireGlobalEvent(name, reason, promise);229} catch (e) {230globalEventFired = true;231async.throwLater(e);232}233234var domEventFired = false;235if (fireDomEvent) {236try {237domEventFired = fireDomEvent(name.toLowerCase(), {238reason: reason,239promise: promise240});241} catch (e) {242domEventFired = true;243async.throwLater(e);244}245}246247if (!globalEventFired && !localEventFired && !domEventFired &&248name === "unhandledRejection") {249CapturedTrace.formatAndLogError(reason, "Unhandled rejection ");250}251};252253function formatNonError(obj) {254var str;255if (typeof obj === "function") {256str = "[function " +257(obj.name || "anonymous") +258"]";259} else {260str = obj.toString();261var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/;262if (ruselessToString.test(str)) {263try {264var newStr = JSON.stringify(obj);265str = newStr;266}267catch(e) {268269}270}271if (str.length === 0) {272str = "(empty array)";273}274}275return ("(<" + snip(str) + ">, no stack trace)");276}277278function snip(str) {279var maxChars = 41;280if (str.length < maxChars) {281return str;282}283return str.substr(0, maxChars - 3) + "...";284}285286var shouldIgnore = function() { return false; };287var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/;288function parseLineInfo(line) {289var matches = line.match(parseLineInfoRegex);290if (matches) {291return {292fileName: matches[1],293line: parseInt(matches[2], 10)294};295}296}297CapturedTrace.setBounds = function(firstLineError, lastLineError) {298if (!CapturedTrace.isSupported()) return;299var firstStackLines = firstLineError.stack.split("\n");300var lastStackLines = lastLineError.stack.split("\n");301var firstIndex = -1;302var lastIndex = -1;303var firstFileName;304var lastFileName;305for (var i = 0; i < firstStackLines.length; ++i) {306var result = parseLineInfo(firstStackLines[i]);307if (result) {308firstFileName = result.fileName;309firstIndex = result.line;310break;311}312}313for (var i = 0; i < lastStackLines.length; ++i) {314var result = parseLineInfo(lastStackLines[i]);315if (result) {316lastFileName = result.fileName;317lastIndex = result.line;318break;319}320}321if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName ||322firstFileName !== lastFileName || firstIndex >= lastIndex) {323return;324}325326shouldIgnore = function(line) {327if (bluebirdFramePattern.test(line)) return true;328var info = parseLineInfo(line);329if (info) {330if (info.fileName === firstFileName &&331(firstIndex <= info.line && info.line <= lastIndex)) {332return true;333}334}335return false;336};337};338339var captureStackTrace = (function stackDetection() {340var v8stackFramePattern = /^\s*at\s*/;341var v8stackFormatter = function(stack, error) {342if (typeof stack === "string") return stack;343344if (error.name !== undefined &&345error.message !== undefined) {346return error.toString();347}348return formatNonError(error);349};350351if (typeof Error.stackTraceLimit === "number" &&352typeof Error.captureStackTrace === "function") {353Error.stackTraceLimit = Error.stackTraceLimit + 6;354stackFramePattern = v8stackFramePattern;355formatStack = v8stackFormatter;356var captureStackTrace = Error.captureStackTrace;357358shouldIgnore = function(line) {359return bluebirdFramePattern.test(line);360};361return function(receiver, ignoreUntil) {362Error.stackTraceLimit = Error.stackTraceLimit + 6;363captureStackTrace(receiver, ignoreUntil);364Error.stackTraceLimit = Error.stackTraceLimit - 6;365};366}367var err = new Error();368369if (typeof err.stack === "string" &&370err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) {371stackFramePattern = /@/;372formatStack = v8stackFormatter;373indentStackFrames = true;374return function captureStackTrace(o) {375o.stack = new Error().stack;376};377}378379var hasStackAfterThrow;380try { throw new Error(); }381catch(e) {382hasStackAfterThrow = ("stack" in e);383}384if (!("stack" in err) && hasStackAfterThrow) {385stackFramePattern = v8stackFramePattern;386formatStack = v8stackFormatter;387return function captureStackTrace(o) {388Error.stackTraceLimit = Error.stackTraceLimit + 6;389try { throw new Error(); }390catch(e) { o.stack = e.stack; }391Error.stackTraceLimit = Error.stackTraceLimit - 6;392};393}394395formatStack = function(stack, error) {396if (typeof stack === "string") return stack;397398if ((typeof error === "object" ||399typeof error === "function") &&400error.name !== undefined &&401error.message !== undefined) {402return error.toString();403}404return formatNonError(error);405};406407return null;408409})([]);410411var fireDomEvent;412var fireGlobalEvent = (function() {413if (util.isNode) {414return function(name, reason, promise) {415if (name === "rejectionHandled") {416return process.emit(name, promise);417} else {418return process.emit(name, reason, promise);419}420};421} else {422var customEventWorks = false;423var anyEventWorks = true;424try {425var ev = new self.CustomEvent("test");426customEventWorks = ev instanceof CustomEvent;427} catch (e) {}428if (!customEventWorks) {429try {430var event = document.createEvent("CustomEvent");431event.initCustomEvent("testingtheevent", false, true, {});432self.dispatchEvent(event);433} catch (e) {434anyEventWorks = false;435}436}437if (anyEventWorks) {438fireDomEvent = function(type, detail) {439var event;440if (customEventWorks) {441event = new self.CustomEvent(type, {442detail: detail,443bubbles: false,444cancelable: true445});446} else if (self.dispatchEvent) {447event = document.createEvent("CustomEvent");448event.initCustomEvent(type, false, true, detail);449}450451return event ? !self.dispatchEvent(event) : false;452};453}454455var toWindowMethodNameMap = {};456toWindowMethodNameMap["unhandledRejection"] = ("on" +457"unhandledRejection").toLowerCase();458toWindowMethodNameMap["rejectionHandled"] = ("on" +459"rejectionHandled").toLowerCase();460461return function(name, reason, promise) {462var methodName = toWindowMethodNameMap[name];463var method = self[methodName];464if (!method) return false;465if (name === "rejectionHandled") {466method.call(self, promise);467} else {468method.call(self, reason, promise);469}470return true;471};472}473})();474475if (typeof console !== "undefined" && typeof console.warn !== "undefined") {476warn = function (message) {477console.warn(message);478};479if (util.isNode && process.stderr.isTTY) {480warn = function(message) {481process.stderr.write("\u001b[31m" + message + "\u001b[39m\n");482};483} else if (!util.isNode && typeof (new Error().stack) === "string") {484warn = function(message) {485console.warn("%c" + message, "color: red");486};487}488}489490return CapturedTrace;491};492493494