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

Commit

Permalink
feat(longStackTraceSpec): handled promise rejection can also render l…
Browse files Browse the repository at this point in the history
…ongstacktrace
  • Loading branch information
JiaLiPassion committed Feb 11, 2017
1 parent f3547cc commit 9859dc9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
22 changes: 18 additions & 4 deletions lib/zone-spec/long-stack-trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/

import {zoneSymbol} from '../common/utils';

const NEWLINE = '\n';
const SEP = ' ------------- ';
const IGNORE_FRAMES = [];
Expand All @@ -23,18 +25,18 @@ function getStacktraceWithUncaughtError(): Error {
function getStacktraceWithCaughtError(): Error {
try {
throw getStacktraceWithUncaughtError();
} catch (error) {
return error;
} catch (err) {
return err;
}
}

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

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

getLongStackTrace: function(error: Error): string {
if (!error) {
return undefined;
}
const task = error[zoneSymbol('currentTask')];
const trace = task && task.data && task.data[creationTrace];
if (!trace) {
return error.stack;
}
return renderLongStackTrace(trace, error.stack);
},

onScheduleTask: function(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any {
const currentTask = Zone.currentTask;
Expand Down
6 changes: 6 additions & 0 deletions lib/zone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,12 @@ const Zone: ZoneType = (function(global: any) {
const queue = promise[symbolValue];
promise[symbolValue] = value;

// record task information in value when error occurs, so we can
// do some additional work such as render longStackTrace
if (state === REJECTED && value instanceof Error) {
value[__symbol__('currentTask')] = Zone.currentTask;
}

for (let i = 0; i < queue.length;) {
scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
}
Expand Down
24 changes: 22 additions & 2 deletions test/zone-spec/long-stack-trace-zone.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ const defineProperty = Object[zoneSymbol('defineProperty')] || Object.defineProp
describe('longStackTraceZone', function() {
let log: Error[];
let lstz: Zone;
let longStackTraceZoneSpec = Zone['longStackTraceZoneSpec'];

beforeEach(function() {
lstz = Zone.current.fork(Zone['longStackTraceZoneSpec']).fork({
lstz = Zone.current.fork(longStackTraceZoneSpec).fork({
name: 'long-stack-trace-zone-test',
onHandleError: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
error: any): boolean => {
Expand Down Expand Up @@ -67,7 +68,7 @@ describe('longStackTraceZone', function() {
});
});

it('should produce long stack traces when reject in promise', function(done) {
it('should produce long stack traces when has uncaught error in promise', function(done) {
lstz.runGuarded(function() {
setTimeout(function() {
setTimeout(function() {
Expand All @@ -91,6 +92,25 @@ describe('longStackTraceZone', function() {
}, 0);
});
});

it('should produce long stack traces when has handled error in promise', function(done) {
lstz.runGuarded(function() {
setTimeout(function() {
setTimeout(function() {
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error('Hello Promise'));
}, 0);
});
promise.catch(function(error) {
expect(longStackTraceZoneSpec.getLongStackTrace(error).split('Elapsed: ').length)
.toBe(4);
done();
});
}, 0);
}, 0);
});
});
});

export let __something__;

0 comments on commit 9859dc9

Please sign in to comment.