@@ -1814,8 +1814,8 @@ const Zone: ZoneType = (function(global: any) {
1814
1814
// This check makes sure that we don't filter frames on name only (must have
1815
1815
// linenumber)
1816
1816
if ( / : \d + : \d + / . test ( frame ) ) {
1817
- // Get rid of the path so that we don't accidintely find function name in path.
1818
- // In chrome the seperator is `(` and `@` in FF and safari
1817
+ // Get rid of the path so that we don't accidentally find function name in path.
1818
+ // In chrome the separator is `(` and `@` in FF and safari
1819
1819
// Chrome: at Zone.run (zone.js:100)
1820
1820
// Chrome: at Zone.run (http://localhost:9876/base/build/lib/zone.js:100:24)
1821
1821
// FireFox: Zone.prototype.run@http ://localhost:9876/base/build/lib/zone.js:101:24
@@ -1858,5 +1858,154 @@ const Zone: ZoneType = (function(global: any) {
1858
1858
// Cause the error to extract the stack frames.
1859
1859
detectZone . runTask ( detectZone . scheduleMacroTask ( 'detect' , detectRunFn , null , ( ) => null , null ) ) ;
1860
1860
1861
+ // detect zone aware frames for output simple stack
1862
+ const zoneAwareStackFrames = { } ;
1863
+
1864
+ function handleDetectError ( error : Error ) {
1865
+ let frames = error . stack ? error . stack . split ( / \n / ) : [ ] ;
1866
+ while ( frames . length ) {
1867
+ let frame = frames . shift ( ) ;
1868
+ // On safari it is possible to have stack frame with no line number.
1869
+ // This check makes sure that we don't filter frames on name only (must have
1870
+ // linenumber)
1871
+ if ( / : \d + : \d + / . test ( frame ) ) {
1872
+ const f = frame . split ( ' [' ) [ 0 ] ;
1873
+ zoneAwareStackFrames [ f ] = f ;
1874
+ }
1875
+ }
1876
+ }
1877
+
1878
+ const detectEmptyZone = Zone . root . fork ( {
1879
+ name : 'detectEmptyZone' ,
1880
+ onHandleError ( parentDelegate , currentZone , targetZone , error ) {
1881
+ parentDelegate . handleError ( targetZone , error ) ;
1882
+ handleDetectError ( error ) ;
1883
+ return false ;
1884
+ }
1885
+ } ) ;
1886
+
1887
+ const detectZoneWithCallbacks = Zone . root . fork ( {
1888
+ name : 'detectCallbackZone' ,
1889
+ onFork : ( parentDelegate , currentZone , targetZone , zoneSpec ) => {
1890
+ handleDetectError ( Error ( 'onFork' ) ) ;
1891
+ return parentDelegate . fork ( targetZone , zoneSpec ) ;
1892
+ } ,
1893
+ onIntercept : ( parentDelegate , currentZone , targetZone , delegate , source ) => {
1894
+ handleDetectError ( Error ( 'onIntercept' ) ) ;
1895
+ return parentDelegate . intercept ( targetZone , delegate , source ) ;
1896
+ } ,
1897
+ onInvoke :
1898
+ ( parentZoneDelegate , currentZone , targetZone , delegate , applyThis , applyArgs , source ) => {
1899
+ handleDetectError ( Error ( 'onInvoke' ) ) ;
1900
+ return parentZoneDelegate . invoke ( targetZone , delegate , applyThis , applyArgs , source ) ;
1901
+ } ,
1902
+ onScheduleTask : ( parentZoneDelegate , currentZone , targetZone , task ) => {
1903
+ handleDetectError ( Error ( 'onScheduleTask' ) ) ;
1904
+ return parentZoneDelegate . scheduleTask ( targetZone , task ) ;
1905
+ } ,
1906
+ onInvokeTask : ( parentZoneDelegate , currentZone , targetZone , task , applyThis , applyArgs ) => {
1907
+ handleDetectError ( Error ( 'onInvokeTask' ) ) ;
1908
+ return parentZoneDelegate . invokeTask ( targetZone , task , applyThis , applyArgs ) ;
1909
+ } ,
1910
+ onCancelTask : ( parentZoneDelegate , currentZone , targetZone , task ) => {
1911
+ handleDetectError ( Error ( 'onCancelTask' ) ) ;
1912
+ return parentZoneDelegate . cancelTask ( targetZone , task ) ;
1913
+ } ,
1914
+
1915
+ onHasTask : ( delegate , current , target , hasTaskState ) => {
1916
+ handleDetectError ( Error ( 'onHasTask' ) ) ;
1917
+ return delegate . hasTask ( target , hasTaskState ) ;
1918
+ } ,
1919
+
1920
+ onHandleError ( parentDelegate , currentZone , targetZone , error ) {
1921
+ parentDelegate . handleError ( targetZone , error ) ;
1922
+ handleDetectError ( error ) ;
1923
+ return false ;
1924
+ }
1925
+ } ) ;
1926
+
1927
+ let detectFn = ( ) => {
1928
+ throw new Error ( 'zoneAwareFrames' ) ;
1929
+ } ;
1930
+
1931
+ let detectPromiseFn = ( ) => {
1932
+ new Promise ( ( resolve , reject ) => {
1933
+ reject ( new Error ( 'zoneAwareFrames' ) ) ;
1934
+ } ) ;
1935
+ } ;
1936
+
1937
+ let detectPromiseCaughtFn = ( ) => {
1938
+ const p = new Promise ( ( resolve , reject ) => {
1939
+ reject ( new Error ( 'zoneAwareFrames' ) ) ;
1940
+ } ) ;
1941
+ p . catch ( err => {
1942
+ throw err ;
1943
+ } ) ;
1944
+ } ;
1945
+
1946
+ // Cause the error to extract the stack frames.
1947
+ detectEmptyZone . runTask (
1948
+ detectEmptyZone . scheduleEventTask ( 'detect' , detectFn , null , ( ) => null , null ) ) ;
1949
+ detectZoneWithCallbacks . runTask (
1950
+ detectZoneWithCallbacks . scheduleEventTask ( 'detect' , detectFn , null , ( ) => null , null ) ) ;
1951
+ detectEmptyZone . runTask (
1952
+ detectEmptyZone . scheduleMacroTask ( 'detect' , detectFn , null , ( ) => null , null ) ) ;
1953
+ detectZoneWithCallbacks . runTask (
1954
+ detectZoneWithCallbacks . scheduleMacroTask ( 'detect' , detectFn , null , ( ) => null , null ) ) ;
1955
+ detectEmptyZone . runTask ( detectEmptyZone . scheduleMicroTask ( 'detect' , detectFn , null , ( ) => null ) ) ;
1956
+ detectZoneWithCallbacks . runTask (
1957
+ detectZoneWithCallbacks . scheduleMicroTask ( 'detect' , detectFn , null , ( ) => null ) ) ;
1958
+
1959
+ detectEmptyZone . runGuarded ( ( ) => {
1960
+ detectEmptyZone . run ( detectFn ) ;
1961
+ } ) ;
1962
+ detectZoneWithCallbacks . runGuarded ( ( ) => {
1963
+ detectEmptyZone . run ( detectFn ) ;
1964
+ } ) ;
1965
+
1966
+ detectEmptyZone . runGuarded ( detectPromiseFn ) ;
1967
+ detectZoneWithCallbacks . runGuarded ( detectPromiseFn ) ;
1968
+
1969
+ detectEmptyZone . runGuarded ( detectPromiseCaughtFn ) ;
1970
+ detectZoneWithCallbacks . runGuarded ( detectPromiseCaughtFn ) ;
1971
+
1972
+ // some functions are not easily to be detected here,
1973
+ // for example Timeout.ZoneTask.invoke, if we want to detect those functions
1974
+ // by detect zone, we have to run all patched APIs, it is too risky
1975
+ // so for those functions, just check whether the stack contains the string or not.
1976
+ const otherZoneAwareFunctionNames = [
1977
+ 'ZoneTask.invoke' , 'ZoneAware' , 'getStacktraceWithUncaughtError' , 'new LongStackTrace' ,
1978
+ 'long-stack-trace'
1979
+ ] ;
1980
+
1981
+ Object . defineProperty ( ZoneAwareError , 'getNonZoneAwareStack' , {
1982
+ value : function ( err : Error ) {
1983
+ if ( err . stack ) {
1984
+ let frames = err . stack . split ( '\n' ) ;
1985
+ const simplifiedFrames : string [ ] = [ ] ;
1986
+ for ( let i = 0 ; i < frames . length ; i ++ ) {
1987
+ const frame = frames [ i ] . split ( ' [' ) [ 0 ] ;
1988
+ const frameWithoutZone = frame . split ( ' [' ) [ 0 ] ;
1989
+ if ( zoneAwareStackFrames . hasOwnProperty ( frameWithoutZone ) &&
1990
+ zoneAwareStackFrames [ frameWithoutZone ] ) {
1991
+ frames . splice ( i , 1 ) ;
1992
+ i -- ;
1993
+ } else if (
1994
+ otherZoneAwareFunctionNames
1995
+ . filter ( f => frame . toLowerCase ( ) . indexOf ( f . toLowerCase ( ) ) !== - 1 )
1996
+ . length > 0 ) {
1997
+ frames . splice ( i , 1 ) ;
1998
+ i -- ;
1999
+ } else {
2000
+ // we still need the zone information on each stack frame
2001
+ simplifiedFrames . push ( frames [ i ] ) ;
2002
+ }
2003
+ }
2004
+ return simplifiedFrames . join ( '\n' ) ;
2005
+ }
2006
+ return err . stack ;
2007
+ }
2008
+ } ) ;
2009
+
1861
2010
return global [ 'Zone' ] = Zone ;
1862
2011
} ) ( typeof window === 'object' && window || typeof self === 'object' && self || global ) ;
0 commit comments