@@ -82,105 +82,104 @@ export function describeNativeComponentFrame(
8282 const previousDispatcher = currentDispatcherRef . H ;
8383 currentDispatcherRef . H = null ;
8484 disableLogs ( ) ;
85+ try {
86+ // NOTE: keep in sync with the implementation in ReactComponentStackFrame
8587
86- // NOTE: keep in sync with the implementation in ReactComponentStackFrame
87-
88- /**
89- * Finding a common stack frame between sample and control errors can be
90- * tricky given the different types and levels of stack trace truncation from
91- * different JS VMs. So instead we'll attempt to control what that common
92- * frame should be through this object method:
93- * Having both the sample and control errors be in the function under the
94- * `DescribeNativeComponentFrameRoot` property, + setting the `name` and
95- * `displayName` properties of the function ensures that a stack
96- * frame exists that has the method name `DescribeNativeComponentFrameRoot` in
97- * it for both control and sample stacks.
98- */
99- const RunInRootFrame = {
100- DetermineComponentFrameRoot ( ) : [ ?string , ?string ] {
101- let control ;
102- try {
103- // This should throw.
104- if ( construct ) {
105- // Something should be setting the props in the constructor.
106- const Fake = function ( ) {
107- throw Error ( ) ;
108- } ;
109- // $FlowFixMe[prop-missing]
110- Object . defineProperty ( Fake . prototype , 'props' , {
111- set : function ( ) {
112- // We use a throwing setter instead of frozen or non-writable props
113- // because that won't throw in a non-strict mode function.
88+ /**
89+ * Finding a common stack frame between sample and control errors can be
90+ * tricky given the different types and levels of stack trace truncation from
91+ * different JS VMs. So instead we'll attempt to control what that common
92+ * frame should be through this object method:
93+ * Having both the sample and control errors be in the function under the
94+ * `DescribeNativeComponentFrameRoot` property, + setting the `name` and
95+ * `displayName` properties of the function ensures that a stack
96+ * frame exists that has the method name `DescribeNativeComponentFrameRoot` in
97+ * it for both control and sample stacks.
98+ */
99+ const RunInRootFrame = {
100+ DetermineComponentFrameRoot ( ) : [ ?string , ?string ] {
101+ let control ;
102+ try {
103+ // This should throw.
104+ if ( construct ) {
105+ // Something should be setting the props in the constructor.
106+ const Fake = function ( ) {
114107 throw Error ( ) ;
115- } ,
116- } ) ;
117- if ( typeof Reflect === 'object' && Reflect . construct ) {
118- // We construct a different control for this case to include any extra
119- // frames added by the construct call.
120- try {
121- Reflect . construct ( Fake , [ ] ) ;
122- } catch ( x ) {
123- control = x ;
108+ } ;
109+ // $FlowFixMe[prop-missing]
110+ Object . defineProperty ( Fake . prototype , 'props' , {
111+ set : function ( ) {
112+ // We use a throwing setter instead of frozen or non-writable props
113+ // because that won't throw in a non-strict mode function.
114+ throw Error ( ) ;
115+ } ,
116+ } ) ;
117+ if ( typeof Reflect === 'object' && Reflect . construct ) {
118+ // We construct a different control for this case to include any extra
119+ // frames added by the construct call.
120+ try {
121+ Reflect . construct ( Fake , [ ] ) ;
122+ } catch ( x ) {
123+ control = x ;
124+ }
125+ Reflect . construct ( fn , [ ] , Fake ) ;
126+ } else {
127+ try {
128+ Fake . call ( ) ;
129+ } catch ( x ) {
130+ control = x ;
131+ }
132+ // $FlowFixMe[prop-missing] found when upgrading Flow
133+ fn . call ( Fake . prototype ) ;
124134 }
125- Reflect . construct ( fn , [ ] , Fake ) ;
126135 } else {
127136 try {
128- Fake . call ( ) ;
137+ throw Error ( ) ;
129138 } catch ( x ) {
130139 control = x ;
131140 }
132- // $FlowFixMe[prop-missing] found when upgrading Flow
133- fn . call ( Fake . prototype ) ;
134- }
135- } else {
136- try {
137- throw Error ( ) ;
138- } catch ( x ) {
139- control = x ;
140- }
141- // TODO(luna): This will currently only throw if the function component
142- // tries to access React/ReactDOM/props. We should probably make this throw
143- // in simple components too
144- const maybePromise = fn ( ) ;
141+ // TODO(luna): This will currently only throw if the function component
142+ // tries to access React/ReactDOM/props. We should probably make this throw
143+ // in simple components too
144+ const maybePromise = fn ( ) ;
145145
146- // If the function component returns a promise, it's likely an async
147- // component, which we don't yet support. Attach a noop catch handler to
148- // silence the error.
149- // TODO: Implement component stacks for async client components?
150- if ( maybePromise && typeof maybePromise . catch === 'function' ) {
151- maybePromise . catch ( ( ) => { } ) ;
146+ // If the function component returns a promise, it's likely an async
147+ // component, which we don't yet support. Attach a noop catch handler to
148+ // silence the error.
149+ // TODO: Implement component stacks for async client components?
150+ if ( maybePromise && typeof maybePromise . catch === 'function' ) {
151+ maybePromise . catch ( ( ) => { } ) ;
152+ }
153+ }
154+ } catch ( sample ) {
155+ // This is inlined manually because closure doesn't do it for us.
156+ if ( sample && control && typeof sample . stack === 'string' ) {
157+ return [ sample . stack , control . stack ] ;
152158 }
153159 }
154- } catch ( sample ) {
155- // This is inlined manually because closure doesn't do it for us.
156- if ( sample && control && typeof sample . stack === 'string' ) {
157- return [ sample . stack , control . stack ] ;
158- }
159- }
160- return [ null , null ] ;
161- } ,
162- } ;
163- // $FlowFixMe[prop-missing]
164- RunInRootFrame . DetermineComponentFrameRoot . displayName =
165- 'DetermineComponentFrameRoot' ;
166- const namePropDescriptor = Object . getOwnPropertyDescriptor (
167- RunInRootFrame . DetermineComponentFrameRoot ,
168- 'name' ,
169- ) ;
170- // Before ES6, the `name` property was not configurable.
171- if ( namePropDescriptor && namePropDescriptor . configurable ) {
172- // V8 utilizes a function's `name` property when generating a stack trace.
173- Object . defineProperty (
160+ return [ null , null ] ;
161+ } ,
162+ } ;
163+ // $FlowFixMe[prop-missing]
164+ RunInRootFrame . DetermineComponentFrameRoot . displayName =
165+ 'DetermineComponentFrameRoot' ;
166+ const namePropDescriptor = Object . getOwnPropertyDescriptor (
174167 RunInRootFrame . DetermineComponentFrameRoot ,
175- // Configurable properties can be updated even if its writable descriptor
176- // is set to `false`.
177- // $FlowFixMe[cannot-write]
178168 'name' ,
179- { value : 'DetermineComponentFrameRoot' } ,
180169 ) ;
181- }
170+ // Before ES6, the `name` property was not configurable.
171+ if ( namePropDescriptor && namePropDescriptor . configurable ) {
172+ // V8 utilizes a function's `name` property when generating a stack trace.
173+ Object . defineProperty (
174+ RunInRootFrame . DetermineComponentFrameRoot ,
175+ // Configurable properties can be updated even if its writable descriptor
176+ // is set to `false`.
177+ // $FlowFixMe[cannot-write]
178+ 'name' ,
179+ { value : 'DetermineComponentFrameRoot' } ,
180+ ) ;
181+ }
182182
183- try {
184183 const [ sampleStack , controlStack ] =
185184 RunInRootFrame . DetermineComponentFrameRoot ( ) ;
186185 if ( sampleStack && controlStack ) {
0 commit comments