"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/bluebird/js/main/captured_trace.js" (7 Feb 2017, 15046 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

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