long-stack-trace-zone.umd.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. 'use strict';
  2. var __assign = (this && this.__assign) || function () {
  3. __assign = Object.assign || function(t) {
  4. for (var s, i = 1, n = arguments.length; i < n; i++) {
  5. s = arguments[i];
  6. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  7. t[p] = s[p];
  8. }
  9. return t;
  10. };
  11. return __assign.apply(this, arguments);
  12. };
  13. /**
  14. * @license Angular v<unknown>
  15. * (c) 2010-2025 Google LLC. https://angular.io/
  16. * License: MIT
  17. */
  18. (function (factory) {
  19. typeof define === 'function' && define.amd ? define(factory) :
  20. factory();
  21. })((function () {
  22. 'use strict';
  23. /**
  24. * @fileoverview
  25. * @suppress {globalThis}
  26. */
  27. function patchLongStackTrace(Zone) {
  28. var NEWLINE = '\n';
  29. var IGNORE_FRAMES = {};
  30. var creationTrace = '__creationTrace__';
  31. var ERROR_TAG = 'STACKTRACE TRACKING';
  32. var SEP_TAG = '__SEP_TAG__';
  33. var sepTemplate = SEP_TAG + '@[native]';
  34. var LongStackTrace = /** @class */ (function () {
  35. function LongStackTrace() {
  36. this.error = getStacktrace();
  37. this.timestamp = new Date();
  38. }
  39. return LongStackTrace;
  40. }());
  41. function getStacktraceWithUncaughtError() {
  42. return new Error(ERROR_TAG);
  43. }
  44. function getStacktraceWithCaughtError() {
  45. try {
  46. throw getStacktraceWithUncaughtError();
  47. }
  48. catch (err) {
  49. return err;
  50. }
  51. }
  52. // Some implementations of exception handling don't create a stack trace if the exception
  53. // isn't thrown, however it's faster not to actually throw the exception.
  54. var error = getStacktraceWithUncaughtError();
  55. var caughtError = getStacktraceWithCaughtError();
  56. var getStacktrace = error.stack
  57. ? getStacktraceWithUncaughtError
  58. : caughtError.stack
  59. ? getStacktraceWithCaughtError
  60. : getStacktraceWithUncaughtError;
  61. function getFrames(error) {
  62. return error.stack ? error.stack.split(NEWLINE) : [];
  63. }
  64. function addErrorStack(lines, error) {
  65. var trace = getFrames(error);
  66. for (var i = 0; i < trace.length; i++) {
  67. var frame = trace[i];
  68. // Filter out the Frames which are part of stack capturing.
  69. if (!IGNORE_FRAMES.hasOwnProperty(frame)) {
  70. lines.push(trace[i]);
  71. }
  72. }
  73. }
  74. function renderLongStackTrace(frames, stack) {
  75. var longTrace = [stack ? stack.trim() : ''];
  76. if (frames) {
  77. var timestamp = new Date().getTime();
  78. for (var i = 0; i < frames.length; i++) {
  79. var traceFrames = frames[i];
  80. var lastTime = traceFrames.timestamp;
  81. var separator = "____________________Elapsed ".concat(timestamp - lastTime.getTime(), " ms; At: ").concat(lastTime);
  82. separator = separator.replace(/[^\w\d]/g, '_');
  83. longTrace.push(sepTemplate.replace(SEP_TAG, separator));
  84. addErrorStack(longTrace, traceFrames.error);
  85. timestamp = lastTime.getTime();
  86. }
  87. }
  88. return longTrace.join(NEWLINE);
  89. }
  90. // if Error.stackTraceLimit is 0, means stack trace
  91. // is disabled, so we don't need to generate long stack trace
  92. // this will improve performance in some test(some test will
  93. // set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698
  94. function stackTracesEnabled() {
  95. // Cast through any since this property only exists on Error in the nodejs
  96. // typings.
  97. return Error.stackTraceLimit > 0;
  98. }
  99. Zone['longStackTraceZoneSpec'] = {
  100. name: 'long-stack-trace',
  101. longStackTraceLimit: 10, // Max number of task to keep the stack trace for.
  102. // add a getLongStackTrace method in spec to
  103. // handle handled reject promise error.
  104. getLongStackTrace: function (error) {
  105. if (!error) {
  106. return undefined;
  107. }
  108. var trace = error[Zone.__symbol__('currentTaskTrace')];
  109. if (!trace) {
  110. return error.stack;
  111. }
  112. return renderLongStackTrace(trace, error.stack);
  113. },
  114. onScheduleTask: function (parentZoneDelegate, currentZone, targetZone, task) {
  115. if (stackTracesEnabled()) {
  116. var currentTask = Zone.currentTask;
  117. var trace = (currentTask && currentTask.data && currentTask.data[creationTrace]) || [];
  118. trace = [new LongStackTrace()].concat(trace);
  119. if (trace.length > this.longStackTraceLimit) {
  120. trace.length = this.longStackTraceLimit;
  121. }
  122. if (!task.data)
  123. task.data = {};
  124. if (task.type === 'eventTask') {
  125. // Fix issue https://github.com/angular/zone.js/issues/1195,
  126. // For event task of browser, by default, all task will share a
  127. // singleton instance of data object, we should create a new one here
  128. // The cast to `any` is required to workaround a closure bug which wrongly applies
  129. // URL sanitization rules to .data access.
  130. task.data = __assign({}, task.data);
  131. }
  132. task.data[creationTrace] = trace;
  133. }
  134. return parentZoneDelegate.scheduleTask(targetZone, task);
  135. },
  136. onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) {
  137. if (stackTracesEnabled()) {
  138. var parentTask = Zone.currentTask || error.task;
  139. if (error instanceof Error && parentTask) {
  140. var longStack = renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack);
  141. try {
  142. error.stack = error.longStack = longStack;
  143. }
  144. catch (err) { }
  145. }
  146. }
  147. return parentZoneDelegate.handleError(targetZone, error);
  148. },
  149. };
  150. function captureStackTraces(stackTraces, count) {
  151. if (count > 0) {
  152. stackTraces.push(getFrames(new LongStackTrace().error));
  153. captureStackTraces(stackTraces, count - 1);
  154. }
  155. }
  156. function computeIgnoreFrames() {
  157. if (!stackTracesEnabled()) {
  158. return;
  159. }
  160. var frames = [];
  161. captureStackTraces(frames, 2);
  162. var frames1 = frames[0];
  163. var frames2 = frames[1];
  164. for (var i = 0; i < frames1.length; i++) {
  165. var frame1 = frames1[i];
  166. if (frame1.indexOf(ERROR_TAG) == -1) {
  167. var match = frame1.match(/^\s*at\s+/);
  168. if (match) {
  169. sepTemplate = match[0] + SEP_TAG + ' (http://localhost)';
  170. break;
  171. }
  172. }
  173. }
  174. for (var i = 0; i < frames1.length; i++) {
  175. var frame1 = frames1[i];
  176. var frame2 = frames2[i];
  177. if (frame1 === frame2) {
  178. IGNORE_FRAMES[frame1] = true;
  179. }
  180. else {
  181. break;
  182. }
  183. }
  184. }
  185. computeIgnoreFrames();
  186. }
  187. patchLongStackTrace(Zone);
  188. }));