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

Commit 8322be8

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(zone): fix #674, handle error.stack readonly case (#675)
1 parent 2a7dd7b commit 8322be8

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

Diff for: lib/zone.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ const Zone: ZoneType = (function(global: any) {
17471747
'long-stack-trace'
17481748
];
17491749

1750-
function attachZoneAndRemoveInternalZoneFrames(error: any) {
1750+
function attachZoneAndRemoveInternalZoneFrames(error: any, zoneAwareError: any) {
17511751
// Save original stack trace
17521752
error.originalStack = error.stack;
17531753
// Process the stack trace and rewrite the frames.
@@ -1789,7 +1789,14 @@ const Zone: ZoneType = (function(global: any) {
17891789
}
17901790
}
17911791
}
1792-
error.stack = error.zoneAwareStack = frames.join('\n');
1792+
const finalStack: string = frames.join('\n');
1793+
try {
1794+
error.stack = error.zoneAwareStack = finalStack;
1795+
} catch (nonWritableErr) {
1796+
// in some browser, the error.stack is readonly such as PhantomJS
1797+
// so we need to store the stack frames to zoneAwareError directly
1798+
zoneAwareError.stack = finalStack;
1799+
}
17931800
}
17941801
}
17951802

@@ -1820,7 +1827,7 @@ const Zone: ZoneType = (function(global: any) {
18201827
this[__symbol__('error')] = error;
18211828
// 1. attach zone information to stack frame
18221829
// 2. remove zone internal stack frames
1823-
attachZoneAndRemoveInternalZoneFrames(error);
1830+
attachZoneAndRemoveInternalZoneFrames(error, this);
18241831

18251832
// use defineProperties here instead of copy property value
18261833
// because of issue #595 which will break angular2.

Diff for: test/common/Error.spec.ts

+20
Original file line numberDiff line numberDiff line change
@@ -405,4 +405,24 @@ describe('Error stack', () => {
405405
}, null, () => null, null);
406406
task.invoke();
407407
}));
408+
409+
it('should be able to generate zone free stack even NativeError stack is readonly', function() {
410+
const _global: any =
411+
typeof window === 'object' && window || typeof self === 'object' && self || global;
412+
const NativeError = _global['__zone_symbol__Error'];
413+
const desc = Object.getOwnPropertyDescriptor(NativeError.prototype, 'stack');
414+
if (desc) {
415+
const originalSet: (value: any) => void = desc.set;
416+
// make stack readonly
417+
desc.set = null;
418+
419+
try {
420+
const error = new Error('test error');
421+
expect(error.stack).toBeTruthy();
422+
assertStackDoesNotContainZoneFrames(error);
423+
} finally {
424+
desc.set = originalSet;
425+
}
426+
}
427+
});
408428
});

0 commit comments

Comments
 (0)