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

Commit 9859dc9

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

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

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

+18-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {zoneSymbol} from '../common/utils';
10+
911
const NEWLINE = '\n';
1012
const SEP = ' ------------- ';
1113
const IGNORE_FRAMES = [];
@@ -23,18 +25,18 @@ function getStacktraceWithUncaughtError(): Error {
2325
function getStacktraceWithCaughtError(): Error {
2426
try {
2527
throw getStacktraceWithUncaughtError();
26-
} catch (error) {
27-
return error;
28+
} catch (err) {
29+
return err;
2830
}
2931
}
3032

3133
// Some implementations of exception handling don't create a stack trace if the exception
3234
// isn't thrown, however it's faster not to actually throw the exception.
3335
const error = getStacktraceWithUncaughtError();
34-
const coughtError = getStacktraceWithCaughtError();
36+
const caughtError = getStacktraceWithCaughtError();
3537
const getStacktrace = error.stack ?
3638
getStacktraceWithUncaughtError :
37-
(coughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
39+
(caughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
3840

3941
function getFrames(error: Error): string[] {
4042
return error.stack ? error.stack.split(NEWLINE) : [];
@@ -74,6 +76,18 @@ Zone['longStackTraceZoneSpec'] = <ZoneSpec>{
7476
name: 'long-stack-trace',
7577
longStackTraceLimit: 10, // Max number of task to keep the stack trace for.
7678

79+
getLongStackTrace: function(error: Error): string {
80+
if (!error) {
81+
return undefined;
82+
}
83+
const task = error[zoneSymbol('currentTask')];
84+
const trace = task && task.data && task.data[creationTrace];
85+
if (!trace) {
86+
return error.stack;
87+
}
88+
return renderLongStackTrace(trace, error.stack);
89+
},
90+
7791
onScheduleTask: function(
7892
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any {
7993
const currentTask = Zone.currentTask;

lib/zone.ts

+6
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

+22-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,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)