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

Commit 36083a7

Browse files
committed
feat(longStackTraceSpec): handled promise rejection can also render longstacktrace
1 parent f3547cc commit 36083a7

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

lib/zone-spec/long-stack-trace.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ function getStacktraceWithUncaughtError(): Error {
2323
function getStacktraceWithCaughtError(): Error {
2424
try {
2525
throw getStacktraceWithUncaughtError();
26-
} catch (error) {
27-
return error;
26+
} catch (err) {
27+
return err;
2828
}
2929
}
3030

3131
// Some implementations of exception handling don't create a stack trace if the exception
3232
// isn't thrown, however it's faster not to actually throw the exception.
3333
const error = getStacktraceWithUncaughtError();
34-
const coughtError = getStacktraceWithCaughtError();
34+
const caughtError = getStacktraceWithCaughtError();
3535
const getStacktrace = error.stack ?
3636
getStacktraceWithUncaughtError :
37-
(coughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
37+
(caughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
3838

3939
function getFrames(error: Error): string[] {
4040
return error.stack ? error.stack.split(NEWLINE) : [];
@@ -73,6 +73,19 @@ function renderLongStackTrace(frames: LongStackTrace[], stack: string): string {
7373
Zone['longStackTraceZoneSpec'] = <ZoneSpec>{
7474
name: 'long-stack-trace',
7575
longStackTraceLimit: 10, // Max number of task to keep the stack trace for.
76+
// add a getLongStackTrace method in spec to
77+
// handle handled reject promise error.
78+
getLongStackTrace: function(error: Error): string {
79+
if (!error) {
80+
return undefined;
81+
}
82+
const task = error[Zone['__symbol__']('currentTask')];
83+
const trace = task && task.data && task.data[creationTrace];
84+
if (!trace) {
85+
return error.stack;
86+
}
87+
return renderLongStackTrace(trace, error.stack);
88+
},
7689

7790
onScheduleTask: function(
7891
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any {

lib/zone.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,12 @@ const Zone: ZoneType = (function(global: any) {
11831183
const queue = promise[symbolValue];
11841184
promise[symbolValue] = value;
11851185

1186+
// record task information in value when error occurs, so we can
1187+
// do some additional work such as render longStackTrace
1188+
if (state === REJECTED && value instanceof Error) {
1189+
value[__symbol__('currentTask')] = Zone.currentTask;
1190+
}
1191+
11861192
for (let i = 0; i < queue.length;) {
11871193
scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
11881194
}

test/zone-spec/long-stack-trace-zone.spec.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ const defineProperty = Object[zoneSymbol('defineProperty')] || Object.defineProp
1212
describe('longStackTraceZone', function() {
1313
let log: Error[];
1414
let lstz: Zone;
15+
let longStackTraceZoneSpec = Zone['longStackTraceZoneSpec'];
1516

1617
beforeEach(function() {
17-
lstz = Zone.current.fork(Zone['longStackTraceZoneSpec']).fork({
18+
lstz = Zone.current.fork(longStackTraceZoneSpec).fork({
1819
name: 'long-stack-trace-zone-test',
1920
onHandleError: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
2021
error: any): boolean => {
@@ -67,7 +68,7 @@ describe('longStackTraceZone', function() {
6768
});
6869
});
6970

70-
it('should produce long stack traces when reject in promise', function(done) {
71+
it('should produce long stack traces when has uncaught error in promise', function(done) {
7172
lstz.runGuarded(function() {
7273
setTimeout(function() {
7374
setTimeout(function() {
@@ -91,6 +92,25 @@ describe('longStackTraceZone', function() {
9192
}, 0);
9293
});
9394
});
95+
96+
it('should produce long stack traces when has handled error in promise', function(done) {
97+
lstz.runGuarded(function() {
98+
setTimeout(function() {
99+
setTimeout(function() {
100+
let promise = new Promise(function(resolve, reject) {
101+
setTimeout(function() {
102+
reject(new Error('Hello Promise'));
103+
}, 0);
104+
});
105+
promise.catch(function(error) {
106+
expect(longStackTraceZoneSpec.getLongStackTrace(error).split('Elapsed: ').length)
107+
.toBe(4);
108+
done();
109+
});
110+
}, 0);
111+
}, 0);
112+
});
113+
});
94114
});
95115

96116
export let __something__;

0 commit comments

Comments
 (0)