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

Commit c183295

Browse files
committed
feat(longStackTraceSpec): handled promise rejection can also render longstacktrace
1 parent 2594940 commit c183295

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

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

+17-4
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ function getStacktraceWithUncaughtError(): Error {
2727
function getStacktraceWithCaughtError(): Error {
2828
try {
2929
throw getStacktraceWithUncaughtError();
30-
} catch (error) {
31-
return error;
30+
} catch (err) {
31+
return err;
3232
}
3333
}
3434

3535
// Some implementations of exception handling don't create a stack trace if the exception
3636
// isn't thrown, however it's faster not to actually throw the exception.
3737
const error = getStacktraceWithUncaughtError();
38-
const coughtError = getStacktraceWithCaughtError();
38+
const caughtError = getStacktraceWithCaughtError();
3939
const getStacktrace = error.stack ?
4040
getStacktraceWithUncaughtError :
41-
(coughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
41+
(caughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
4242

4343
function getFrames(error: Error): string[] {
4444
return error.stack ? error.stack.split(NEWLINE) : [];
@@ -77,6 +77,19 @@ function renderLongStackTrace(frames: LongStackTrace[], stack: string): string {
7777
Zone['longStackTraceZoneSpec'] = <ZoneSpec>{
7878
name: 'long-stack-trace',
7979
longStackTraceLimit: 10, // Max number of task to keep the stack trace for.
80+
// add a getLongStackTrace method in spec to
81+
// handle handled reject promise error.
82+
getLongStackTrace: function(error: Error): string {
83+
if (!error) {
84+
return undefined;
85+
}
86+
const task = error[Zone['__symbol__']('currentTask')];
87+
const trace = task && task.data && task.data[creationTrace];
88+
if (!trace) {
89+
return error.stack;
90+
}
91+
return renderLongStackTrace(trace, error.stack);
92+
},
8093

8194
onScheduleTask: function(
8295
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any {

lib/zone.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,12 @@ const Zone: ZoneType = (function(global: any) {
13321332
const queue = promise[symbolValue];
13331333
promise[symbolValue] = value;
13341334

1335+
// record task information in value when error occurs, so we can
1336+
// do some additional work such as render longStackTrace
1337+
if (state === REJECTED && value instanceof Error) {
1338+
value[__symbol__('currentTask')] = Zone.currentTask;
1339+
}
1340+
13351341
for (let i = 0; i < queue.length;) {
13361342
scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
13371343
}

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

+23-2
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,26 @@ describe('longStackTraceZone', function() {
9192
}, 0);
9293
});
9394
});
95+
96+
it('should produce long stack traces when handling 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+
// should be able to get long stack trace
107+
const longStackFrames: string = longStackTraceZoneSpec.getLongStackTrace(error);
108+
expect(longStackFrames.split('Elapsed: ').length).toBe(4);
109+
done();
110+
});
111+
}, 0);
112+
}, 0);
113+
});
114+
});
94115
});
95116

96117
export let __something__;

0 commit comments

Comments
 (0)