Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 7a5e2a2

Browse files
committed
fix(error): fix #698, don not generate long stack trace when Error.stackTraceLimit = 0, add null check
1 parent 7535fca commit 7a5e2a2

File tree

2 files changed

+53
-15
lines changed

2 files changed

+53
-15
lines changed

Diff for: lib/zone-spec/long-stack-trace.ts

+30-15
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function addErrorStack(lines: string[], error: Error): void {
5858
}
5959

6060
function renderLongStackTrace(frames: LongStackTrace[], stack: string): string {
61-
const longTrace: string[] = [stack.trim()];
61+
const longTrace: string[] = [stack ? stack.trim() : ''];
6262

6363
if (frames) {
6464
let timestamp = new Date().getTime();
@@ -97,26 +97,38 @@ function renderLongStackTrace(frames: LongStackTrace[], stack: string): string {
9797

9898
onScheduleTask: function(
9999
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any {
100-
const currentTask = Zone.currentTask;
101-
let trace = currentTask && currentTask.data && (currentTask.data as any)[creationTrace] || [];
102-
trace = [new LongStackTrace()].concat(trace);
103-
if (trace.length > this.longStackTraceLimit) {
104-
trace.length = this.longStackTraceLimit;
100+
if (Error.stackTraceLimit > 0) {
101+
// if Error.stackTraceLimit is 0, means stack trace
102+
// is disabled, so we don't need to generate long stack trace
103+
// this will improve performance in some test(some test will
104+
// set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698
105+
const currentTask = Zone.currentTask;
106+
let trace = currentTask && currentTask.data && (currentTask.data as any)[creationTrace] || [];
107+
trace = [new LongStackTrace()].concat(trace);
108+
if (trace.length > this.longStackTraceLimit) {
109+
trace.length = this.longStackTraceLimit;
110+
}
111+
if (!task.data) task.data = {};
112+
(task.data as any)[creationTrace] = trace;
105113
}
106-
if (!task.data) task.data = {};
107-
(task.data as any)[creationTrace] = trace;
108114
return parentZoneDelegate.scheduleTask(targetZone, task);
109115
},
110116

111117
onHandleError: function(
112118
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any): boolean {
113-
const parentTask = Zone.currentTask || error.task;
114-
if (error instanceof Error && parentTask) {
115-
const longStack =
116-
renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack);
117-
try {
118-
error.stack = (error as any).longStack = longStack;
119-
} catch (err) {
119+
if (Error.stackTraceLimit > 0) {
120+
// if Error.stackTraceLimit is 0, means stack trace
121+
// is disabled, so we don't need to generate long stack trace
122+
// this will improve performance in some test(some test will
123+
// set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698
124+
const parentTask = Zone.currentTask || error.task;
125+
if (error instanceof Error && parentTask) {
126+
const longStack =
127+
renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack);
128+
try {
129+
error.stack = (error as any).longStack = longStack;
130+
} catch (err) {
131+
}
120132
}
121133
}
122134
return parentZoneDelegate.handleError(targetZone, error);
@@ -131,6 +143,9 @@ function captureStackTraces(stackTraces: string[][], count: number): void {
131143
}
132144

133145
function computeIgnoreFrames() {
146+
if (Error.stackTraceLimit <= 0) {
147+
return;
148+
}
134149
const frames: string[][] = [];
135150
captureStackTraces(frames, 2);
136151
const frames1 = frames[0];

Diff for: test/zone-spec/long-stack-trace-zone.spec.ts

+23
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,27 @@ describe('longStackTraceZone', function() {
120120
}, 0);
121121
});
122122
});
123+
124+
it('should not produce long stack traces if Error.stackTraceLimit = 0', function(done) {
125+
const originalStackTraceLimit = Error.stackTraceLimit;
126+
const detectError = new Error();
127+
lstz.run(function() {
128+
setTimeout(function() {
129+
setTimeout(function() {
130+
setTimeout(function() {
131+
if (detectError.stack) {
132+
expectElapsed(log[0].stack, 1);
133+
Error.stackTraceLimit = originalStackTraceLimit;
134+
} else {
135+
// IE stack trace will be undefined
136+
expect(log[0].stack).toBeFalsy();
137+
}
138+
done();
139+
}, 0);
140+
Error.stackTraceLimit = 0;
141+
throw new Error('Hello');
142+
}, 0);
143+
}, 0);
144+
});
145+
});
123146
});

0 commit comments

Comments
 (0)