From 2d309141749e3f5384cad98d5e87905d29599d55 Mon Sep 17 00:00:00 2001 From: JiaLiPassion Date: Wed, 8 Mar 2017 09:58:11 +0900 Subject: [PATCH] fix(error): fix #618, ZoneAwareError should copy Error's static propeties (#647) --- karma-build.conf.js | 1 + karma-dist.conf.js | 1 + lib/zone.ts | 19 +++++++++++++++++++ test/common/Error.spec.ts | 12 ++++++++++++ test/custom_error.ts | 14 ++++++++++++++ test/node_entry_point.ts | 1 + 6 files changed, 48 insertions(+) create mode 100644 test/custom_error.ts diff --git a/karma-build.conf.js b/karma-build.conf.js index d0eba8bb6..746826a87 100644 --- a/karma-build.conf.js +++ b/karma-build.conf.js @@ -9,6 +9,7 @@ module.exports = function (config) { require('./karma-base.conf.js')(config); config.files.push('build/test/wtf_mock.js'); + config.files.push('build/test/custom_error.js'); config.files.push('build/lib/zone.js'); config.files.push('build/test/main.js'); }; diff --git a/karma-dist.conf.js b/karma-dist.conf.js index bc4adf047..844aef697 100644 --- a/karma-dist.conf.js +++ b/karma-dist.conf.js @@ -9,6 +9,7 @@ module.exports = function (config) { require('./karma-base.conf.js')(config); config.files.push('build/test/wtf_mock.js'); + config.files.push('build/test/custom_error.js'); config.files.push('dist/zone.js'); config.files.push('dist/async-test.js'); config.files.push('dist/fake-async-test.js'); diff --git a/lib/zone.ts b/lib/zone.ts index a5336e314..225cc0b55 100644 --- a/lib/zone.ts +++ b/lib/zone.ts @@ -1744,6 +1744,25 @@ const Zone: ZoneType = (function(global: any) { ZoneAwareError[Zone.__symbol__('blacklistedStackFrames')] = blackListedStackFrames; ZoneAwareError[stackRewrite] = false; + // those properties need special handling + const specialPropertyNames = ['stackTraceLimit', 'captureStackTrace', 'prepareStackTrace']; + // those properties of NativeError should be set to ZoneAwareError + const nativeErrorProperties = Object.keys(NativeError); + if (nativeErrorProperties) { + nativeErrorProperties.forEach(prop => { + if (specialPropertyNames.filter(sp => sp === prop).length === 0) { + Object.defineProperty(ZoneAwareError, prop, { + get: function() { + return NativeError[prop]; + }, + set: function(value) { + NativeError[prop] = value; + } + }); + } + }); + } + if (NativeError.hasOwnProperty('stackTraceLimit')) { // Extend default stack limit as we will be removing few frames. NativeError.stackTraceLimit = Math.max(NativeError.stackTraceLimit, 15); diff --git a/test/common/Error.spec.ts b/test/common/Error.spec.ts index 111cfc761..ffb9f89a0 100644 --- a/test/common/Error.spec.ts +++ b/test/common/Error.spec.ts @@ -157,6 +157,18 @@ describe('ZoneAwareError', () => { expect(error1.message).toEqual('test new error message'); }); + it('should copy customized NativeError properties to ZoneAwareError', () => { + const spy = jasmine.createSpy('errorCustomFunction'); + const NativeError = global[Zone['__symbol__']('Error')]; + NativeError.customFunction = function(args) { + spy(args); + }; + expect(Error['customProperty']).toBe('customProperty'); + expect(typeof Error['customFunction']).toBe('function'); + Error['customFunction']('test'); + expect(spy).toHaveBeenCalledWith('test'); + }); + it('should show zone names in stack frames and remove extra frames', () => { const rootZone = getRootZone(); const innerZone = rootZone.fork({name: 'InnerZone'}); diff --git a/test/custom_error.ts b/test/custom_error.ts new file mode 100644 index 000000000..9fda6eb6f --- /dev/null +++ b/test/custom_error.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +'use strict'; +(function(global) { + const NativeError = global['Error']; + NativeError.customProperty = 'customProperty'; + NativeError.customFunction = function() {}; +})(typeof window === 'object' && window || typeof self === 'object' && self || global); diff --git a/test/node_entry_point.ts b/test/node_entry_point.ts index 840d820e5..cca820e25 100644 --- a/test/node_entry_point.ts +++ b/test/node_entry_point.ts @@ -8,6 +8,7 @@ // Must be loaded before zone loads, so that zone can detect WTF. import './wtf_mock'; +import './custom_error'; // Setup tests for Zone without microtask support import '../lib/zone';