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

fix(error): fix #674, handle error.stack readonly case #675

Merged
merged 1 commit into from
Mar 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions lib/zone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,7 @@ const Zone: ZoneType = (function(global: any) {
'long-stack-trace'
];

function attachZoneAndRemoveInternalZoneFrames(error: any) {
function attachZoneAndRemoveInternalZoneFrames(error: any, zoneAwareError: any) {
// Save original stack trace
error.originalStack = error.stack;
// Process the stack trace and rewrite the frames.
Expand Down Expand Up @@ -1789,7 +1789,14 @@ const Zone: ZoneType = (function(global: any) {
}
}
}
error.stack = error.zoneAwareStack = frames.join('\n');
const finalStack: string = frames.join('\n');
try {
error.stack = error.zoneAwareStack = finalStack;
} catch (nonWritableErr) {
// in some browser, the error.stack is readonly such as PhantomJS
// so we need to store the stack frames to zoneAwareError directly
zoneAwareError.stack = finalStack;
}
}
}

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

// use defineProperties here instead of copy property value
// because of issue #595 which will break angular2.
Expand Down
20 changes: 20 additions & 0 deletions test/common/Error.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,4 +405,24 @@ describe('Error stack', () => {
}, null, () => null, null);
task.invoke();
}));

it('should be able to generate zone free stack even NativeError stack is readonly', function() {
const _global: any =
typeof window === 'object' && window || typeof self === 'object' && self || global;
const NativeError = _global['__zone_symbol__Error'];
const desc = Object.getOwnPropertyDescriptor(NativeError.prototype, 'stack');
if (desc) {
const originalSet: (value: any) => void = desc.set;
// make stack readonly
desc.set = null;

try {
const error = new Error('test error');
expect(error.stack).toBeTruthy();
assertStackDoesNotContainZoneFrames(error);
} finally {
desc.set = originalSet;
}
}
});
});