@@ -1657,6 +1657,8 @@ const Zone: ZoneType = (function(global: any) {
1657
1657
// in NativeError
1658
1658
createProperty ( props , 'originalStack' ) ;
1659
1659
createProperty ( props , 'zoneAwareStack' ) ;
1660
+ // in IE11, stack is not in prototype
1661
+ createProperty ( props , 'stack' ) ;
1660
1662
1661
1663
// define toString, toSource as method property
1662
1664
createMethodProperty ( props , 'toString' ) ;
@@ -1700,32 +1702,17 @@ const Zone: ZoneType = (function(global: any) {
1700
1702
'long-stack-trace'
1701
1703
] ;
1702
1704
1703
- /**
1704
- * This is ZoneAwareError which processes the stack frame and cleans up extra frames as well as
1705
- * adds zone information to it.
1706
- */
1707
- function ZoneAwareError ( ) {
1708
- // make sure we have a valid this
1709
- // if this is undefined(call Error without new) or this is global
1710
- // or this is some other objects, we should force to create a
1711
- // valid ZoneAwareError by call Object.create()
1712
- if ( ! ( this instanceof ZoneAwareError ) ) {
1713
- return ZoneAwareError . apply ( Object . create ( ZoneAwareError . prototype ) , arguments ) ;
1714
- }
1715
- // Create an Error.
1716
- let error : Error = NativeError . apply ( this , arguments ) ;
1717
- this [ __symbol__ ( 'error' ) ] = error ;
1718
-
1705
+ function attachZoneAndRemoveInternalZoneFrames ( error : any ) {
1719
1706
// Save original stack trace
1720
1707
error . originalStack = error . stack ;
1721
-
1722
1708
// Process the stack trace and rewrite the frames.
1723
1709
if ( ( ZoneAwareError as any ) [ stackRewrite ] && error . originalStack ) {
1724
1710
let frames : string [ ] = error . originalStack . split ( '\n' ) ;
1725
1711
let zoneFrame = _currentZoneFrame ;
1726
1712
let i = 0 ;
1727
1713
// Find the first frame
1728
- while ( i < frames . length && zoneAwareFrame . filter ( zf => zf === frames [ i ] ) . length === 0 ) {
1714
+ while ( i < frames . length &&
1715
+ zoneAwareFrame . filter ( zf => zf . trim ( ) === frames [ i ] . trim ( ) ) . length === 0 ) {
1729
1716
i ++ ;
1730
1717
}
1731
1718
for ( ; i < frames . length && zoneFrame ; i ++ ) {
@@ -1758,9 +1745,41 @@ const Zone: ZoneType = (function(global: any) {
1758
1745
}
1759
1746
error . stack = error . zoneAwareStack = frames . join ( '\n' ) ;
1760
1747
}
1748
+ }
1749
+
1750
+ /**
1751
+ * This is ZoneAwareError which processes the stack frame and cleans up extra frames as well as
1752
+ * adds zone information to it.
1753
+ */
1754
+ function ZoneAwareError ( ) {
1755
+ // make sure we have a valid this
1756
+ // if this is undefined(call Error without new) or this is global
1757
+ // or this is some other objects, we should force to create a
1758
+ // valid ZoneAwareError by call Object.create()
1759
+ if ( ! ( this instanceof ZoneAwareError ) ) {
1760
+ return ZoneAwareError . apply ( Object . create ( ZoneAwareError . prototype ) , arguments ) ;
1761
+ }
1762
+ // Create an Error.
1763
+ let error : Error = NativeError . apply ( this , arguments ) ;
1764
+ if ( ! error . stack ) {
1765
+ // in IE, the error.stack will be undefined
1766
+ // when error was constructed, it will only
1767
+ // be available when throw
1768
+ try {
1769
+ throw error ;
1770
+ } catch ( err ) {
1771
+ error = err ;
1772
+ }
1773
+ }
1774
+ this [ __symbol__ ( 'error' ) ] = error ;
1775
+ // 1. attach zone information to stack frame
1776
+ // 2. remove zone internal stack frames
1777
+ attachZoneAndRemoveInternalZoneFrames ( error ) ;
1778
+
1761
1779
// use defineProperties here instead of copy property value
1762
1780
// because of issue #595 which will break angular2.
1763
- Object . defineProperties ( this , getErrorPropertiesForPrototype ( Object . getPrototypeOf ( this ) ) ) ;
1781
+ const props = getErrorPropertiesForPrototype ( Object . getPrototypeOf ( this ) ) ;
1782
+ Object . defineProperties ( this , props ) ;
1764
1783
return this ;
1765
1784
}
1766
1785
@@ -1896,17 +1915,44 @@ const Zone: ZoneType = (function(global: any) {
1896
1915
} ) as Zone ;
1897
1916
// carefully constructor a stack frame which contains all of the frames of interest which
1898
1917
// need to be detected and blacklisted.
1918
+
1919
+ // use this method to handle
1920
+ // 1. IE issue, the error.stack can only be not undefined after throw
1921
+ // 2. handle Error(...) without new options
1922
+ const throwError = ( message : string , withNew : boolean = true ) => {
1923
+ let error ;
1924
+ try {
1925
+ if ( withNew ) {
1926
+ throw new Error ( message ) ;
1927
+ } else {
1928
+ throw Error ( message ) ;
1929
+ }
1930
+ } catch ( err ) {
1931
+ error = err ;
1932
+ }
1933
+ return error ;
1934
+ } ;
1935
+
1936
+ const nativeStackTraceLimit = NativeError . stackTraceLimit ;
1937
+ // in some system/browser, some additional stack frames
1938
+ // will be generated (such as inline function)
1939
+ // so the the stack frame to check ZoneAwareError Start
1940
+ // maybe ignored because the frame's number will exceed
1941
+ // stackTraceLimit, so we just set stackTraceLimit to 100
1942
+ // and reset after all detect work is done.
1943
+ NativeError . stackTraceLimit = 100 ;
1899
1944
let detectRunFn = ( ) => {
1900
1945
detectZone . run ( ( ) => {
1901
1946
detectZone . runGuarded ( ( ) => {
1902
- throw new Error ( 'blacklistStackFrames' ) ;
1947
+ throw throwError ( 'blacklistStackFrames' ) ;
1903
1948
} ) ;
1904
1949
} ) ;
1905
1950
} ;
1951
+
1906
1952
let detectRunWithoutNewFn = ( ) => {
1907
1953
detectZone . run ( ( ) => {
1908
1954
detectZone . runGuarded ( ( ) => {
1909
- throw Error ( 'blacklistStackFrames' ) ;
1955
+ throw throwError ( 'blacklistStackFrames' , false ) ;
1910
1956
} ) ;
1911
1957
} ) ;
1912
1958
} ;
@@ -1948,33 +1994,40 @@ const Zone: ZoneType = (function(global: any) {
1948
1994
const detectZoneWithCallbacks = Zone . root . fork ( {
1949
1995
name : 'detectCallbackZone' ,
1950
1996
onFork : ( parentDelegate , currentZone , targetZone , zoneSpec ) => {
1951
- handleDetectError ( Error ( 'onFork' ) ) ;
1997
+ handleDetectError ( throwError ( 'onFork' ) ) ;
1998
+ handleDetectError ( throwError ( 'onFork' , false ) ) ;
1952
1999
return parentDelegate . fork ( targetZone , zoneSpec ) ;
1953
2000
} ,
1954
2001
onIntercept : ( parentDelegate , currentZone , targetZone , delegate , source ) => {
1955
- handleDetectError ( Error ( 'onIntercept' ) ) ;
2002
+ handleDetectError ( throwError ( 'onIntercept' ) ) ;
2003
+ handleDetectError ( throwError ( 'onIntercept' , false ) ) ;
1956
2004
return parentDelegate . intercept ( targetZone , delegate , source ) ;
1957
2005
} ,
1958
2006
onInvoke :
1959
2007
( parentZoneDelegate , currentZone , targetZone , delegate , applyThis , applyArgs , source ) => {
1960
- handleDetectError ( Error ( 'onInvoke' ) ) ;
2008
+ handleDetectError ( throwError ( 'onInvoke' ) ) ;
2009
+ handleDetectError ( throwError ( 'onInvoke' , false ) ) ;
1961
2010
return parentZoneDelegate . invoke ( targetZone , delegate , applyThis , applyArgs , source ) ;
1962
2011
} ,
1963
2012
onScheduleTask : ( parentZoneDelegate , currentZone , targetZone , task ) => {
1964
- handleDetectError ( Error ( 'onScheduleTask' ) ) ;
2013
+ handleDetectError ( throwError ( 'onScheduleTask' ) ) ;
2014
+ handleDetectError ( throwError ( 'onScheduleTask' , false ) ) ;
1965
2015
return parentZoneDelegate . scheduleTask ( targetZone , task ) ;
1966
2016
} ,
1967
2017
onInvokeTask : ( parentZoneDelegate , currentZone , targetZone , task , applyThis , applyArgs ) => {
1968
- handleDetectError ( Error ( 'onInvokeTask' ) ) ;
2018
+ handleDetectError ( throwError ( 'onInvokeTask' ) ) ;
2019
+ handleDetectError ( throwError ( 'onInvokeTask' , false ) ) ;
1969
2020
return parentZoneDelegate . invokeTask ( targetZone , task , applyThis , applyArgs ) ;
1970
2021
} ,
1971
2022
onCancelTask : ( parentZoneDelegate , currentZone , targetZone , task ) => {
1972
- handleDetectError ( Error ( 'onCancelTask' ) ) ;
2023
+ handleDetectError ( throwError ( 'onCancelTask' ) ) ;
2024
+ handleDetectError ( throwError ( 'onCancelTask' , false ) ) ;
1973
2025
return parentZoneDelegate . cancelTask ( targetZone , task ) ;
1974
2026
} ,
1975
2027
1976
2028
onHasTask : ( delegate , current , target , hasTaskState ) => {
1977
- handleDetectError ( Error ( 'onHasTask' ) ) ;
2029
+ handleDetectError ( throwError ( 'onHasTask' ) ) ;
2030
+ handleDetectError ( throwError ( 'onHasTask' , false ) ) ;
1978
2031
return delegate . hasTask ( target , hasTaskState ) ;
1979
2032
} ,
1980
2033
@@ -1986,18 +2039,37 @@ const Zone: ZoneType = (function(global: any) {
1986
2039
} ) ;
1987
2040
1988
2041
let detectFn = ( ) => {
1989
- throw Error ( 'zoneAwareFrames' ) ;
2042
+ throw throwError ( 'zoneAwareFrames' ) ;
2043
+ } ;
2044
+
2045
+ let detectWithoutNewFn = ( ) => {
2046
+ throw throwError ( 'zoneAwareFrames' , false ) ;
1990
2047
} ;
1991
2048
1992
2049
let detectPromiseFn = ( ) => {
1993
2050
new Promise ( ( resolve , reject ) => {
1994
- reject ( Error ( 'zoneAwareFrames' ) ) ;
2051
+ reject ( throwError ( 'zoneAwareFrames' ) ) ;
2052
+ } ) ;
2053
+ } ;
2054
+
2055
+ let detectPromiseWithoutNewFn = ( ) => {
2056
+ new Promise ( ( resolve , reject ) => {
2057
+ reject ( throwError ( 'zoneAwareFrames' , false ) ) ;
1995
2058
} ) ;
1996
2059
} ;
1997
2060
1998
2061
let detectPromiseCaughtFn = ( ) => {
1999
2062
const p = new Promise ( ( resolve , reject ) => {
2000
- reject ( Error ( 'zoneAwareFrames' ) ) ;
2063
+ reject ( throwError ( 'zoneAwareFrames' ) ) ;
2064
+ } ) ;
2065
+ p . catch ( err => {
2066
+ throw err ;
2067
+ } ) ;
2068
+ } ;
2069
+
2070
+ let detectPromiseCaughtWithoutNewFn = ( ) => {
2071
+ const p = new Promise ( ( resolve , reject ) => {
2072
+ reject ( throwError ( 'zoneAwareFrames' , false ) ) ;
2001
2073
} ) ;
2002
2074
p . catch ( err => {
2003
2075
throw err ;
@@ -2024,11 +2096,38 @@ const Zone: ZoneType = (function(global: any) {
2024
2096
detectEmptyZone . run ( detectFn ) ;
2025
2097
} ) ;
2026
2098
2099
+ detectEmptyZone . runTask (
2100
+ detectEmptyZone . scheduleEventTask ( 'detect' , detectWithoutNewFn , null , ( ) => null , null ) ) ;
2101
+ detectZoneWithCallbacks . runTask ( detectZoneWithCallbacks . scheduleEventTask (
2102
+ 'detect' , detectWithoutNewFn , null , ( ) => null , null ) ) ;
2103
+ detectEmptyZone . runTask (
2104
+ detectEmptyZone . scheduleMacroTask ( 'detect' , detectWithoutNewFn , null , ( ) => null , null ) ) ;
2105
+ detectZoneWithCallbacks . runTask ( detectZoneWithCallbacks . scheduleMacroTask (
2106
+ 'detect' , detectWithoutNewFn , null , ( ) => null , null ) ) ;
2107
+ detectEmptyZone . runTask (
2108
+ detectEmptyZone . scheduleMicroTask ( 'detect' , detectWithoutNewFn , null , ( ) => null ) ) ;
2109
+ detectZoneWithCallbacks . runTask (
2110
+ detectZoneWithCallbacks . scheduleMicroTask ( 'detect' , detectWithoutNewFn , null , ( ) => null ) ) ;
2111
+
2112
+ detectEmptyZone . runGuarded ( ( ) => {
2113
+ detectEmptyZone . run ( detectWithoutNewFn ) ;
2114
+ } ) ;
2115
+ detectZoneWithCallbacks . runGuarded ( ( ) => {
2116
+ detectEmptyZone . run ( detectWithoutNewFn ) ;
2117
+ } ) ;
2118
+
2027
2119
detectEmptyZone . runGuarded ( detectPromiseFn ) ;
2028
2120
detectZoneWithCallbacks . runGuarded ( detectPromiseFn ) ;
2029
2121
2122
+ detectEmptyZone . runGuarded ( detectPromiseWithoutNewFn ) ;
2123
+ detectZoneWithCallbacks . runGuarded ( detectPromiseWithoutNewFn ) ;
2124
+
2030
2125
detectEmptyZone . runGuarded ( detectPromiseCaughtFn ) ;
2031
2126
detectZoneWithCallbacks . runGuarded ( detectPromiseCaughtFn ) ;
2032
2127
2128
+ detectEmptyZone . runGuarded ( detectPromiseCaughtWithoutNewFn ) ;
2129
+ detectZoneWithCallbacks . runGuarded ( detectPromiseCaughtWithoutNewFn ) ;
2130
+ NativeError . stackTraceLimit = nativeStackTraceLimit ;
2131
+
2033
2132
return global [ 'Zone' ] = Zone ;
2034
2133
} ) ( typeof window === 'object' && window || typeof self === 'object' && self || global ) ;
0 commit comments