Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build Component Stacks from Native Stack Frames #18561

Merged
merged 9 commits into from
Apr 10, 2020

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Apr 9, 2020

Instead of using displayName/name and source location from jsxDEV, this uses a hack to extract the native stack frame of the function. That way it's zero-cost when an error is not hit and we can feel good about including it in production environments too.

It works by calling each function once with invalid input and intentionally causing it to throw and catching the error. This should be ok since they shouldn't have side-effects.

By doing so we get the stack frame of that function somewhere in the error's stack. We then compare it to a control stack to figure out which one is the next frame after that. This should be the frame of the component. We use that to build a stack.

This stack should be parsable by off-the-shelf cross-browser stack parsing libraries.

The idea is to throw as early as possible. Ideally it's the first line such as the built-in super call of a class or the destructuring of props in the argument position. It could however be slightly later which might be slightly confusing to see the line of the first hook for example. Source code aware tooling could adjust this number to the previous function definition before the offset. If it doesn't throw at all such as if no hooks and no props are used, then we can't figure out the line number.

This doesn't give us the offset of the JSX call so it's slightly worse than the source info transform in that regard. However, it has the benefit of yielding the client-side source position rather than file name source position. This allows linkifying the location on the client so you can jump to source. It does require source maps to do so but it can piggyback on standard error logging strategies. This PR make the flag take over both DEV and prod so the source location from the transform is not used for consistency.

If this ends up being considered worse than the JSX transform due to the lack of JSX callsites, I have another idea to use the second error recovery pass in DEV to collect exact JSX callsites using stack frames but that's way more complicated and code. We wouldn't ship that to prod anyway.

TODO:

  • Fix bug when a native class doesn't extend React.Component and can't be called
  • Add fixture for easy cross-browser testing
    • There's an issue with native classes in Safari because Safari adds the "construct" call to the stack.

@sebmarkbage sebmarkbage requested a review from gaearon April 9, 2020 18:59
@sebmarkbage sebmarkbage marked this pull request as draft April 9, 2020 18:59
@codesandbox-ci
Copy link

codesandbox-ci bot commented Apr 9, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit fbb0189:

Sandbox Source
jolly-aryabhata-u70ro Configuration

@facebook-github-bot facebook-github-bot added React Core Team Opened by a member of the React Core Team CLA Signed labels Apr 9, 2020
@sizebot
Copy link

sizebot commented Apr 9, 2020

Details of bundled changes.

Comparing: af1b039...fbb0189

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.1% +0.1% 633.21 KB 633.97 KB 133.49 KB 133.61 KB UMD_DEV
react-art.production.min.js 0.0% 0.0% 107.11 KB 107.11 KB 32.46 KB 32.46 KB UMD_PROD
react-art.development.js +0.1% +0.1% 537.57 KB 538.28 KB 115.92 KB 116.03 KB NODE_DEV
react-art.production.min.js 0.0% 0.0% 72.1 KB 72.11 KB 21.65 KB 21.65 KB NODE_PROD
ReactART-dev.js +0.8% +1.1% 599.95 KB 604.99 KB 125.8 KB 127.21 KB FB_WWW_DEV
ReactART-prod.js 🔺+0.7% 🔺+1.1% 248.57 KB 250.43 KB 42.06 KB 42.54 KB FB_WWW_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js +0.1% 0.0% 568.97 KB 569.41 KB 118.38 KB 118.44 KB UMD_DEV
react-test-renderer.production.min.js 0.0% 0.0% 74.13 KB 74.13 KB 22.53 KB 22.53 KB UMD_PROD
react-test-renderer-shallow.production.min.js 0.0% -0.0% 12.73 KB 12.73 KB 3.96 KB 3.96 KB UMD_PROD
react-test-renderer.development.js +0.1% +0.1% 542.53 KB 542.95 KB 117.01 KB 117.09 KB NODE_DEV
react-test-renderer.production.min.js 0.0% 0.0% 73.93 KB 73.93 KB 22.22 KB 22.23 KB NODE_PROD
ReactTestRenderer-dev.js +0.1% 0.0% 576.84 KB 577.26 KB 121.73 KB 121.79 KB FB_WWW_DEV

react

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react.development.js -0.0% +0.4% 101.87 KB 101.84 KB 24.64 KB 24.74 KB UMD_DEV
JSXDEVRuntime-dev.js +32.3% +28.4% 28.79 KB 38.1 KB 8.44 KB 10.83 KB FB_WWW_DEV
react-jsx-runtime.development.js +12.2% +7.9% 26.85 KB 30.14 KB 8.25 KB 8.89 KB NODE_DEV
react-jsx-runtime.production.min.js 0.0% 🔺+0.2% 947 B 947 B 594 B 595 B NODE_PROD
JSXRuntime-dev.js +31.7% +27.7% 29.38 KB 38.68 KB 8.61 KB 11 KB FB_WWW_DEV
react.development.js -0.1% +0.6% 63.49 KB 63.43 KB 16.95 KB 17.06 KB NODE_DEV
react.production.min.js 0.0% 0.0% 6.32 KB 6.32 KB 2.62 KB 2.62 KB NODE_PROD
React-dev.js +6.8% +8.5% 91.6 KB 97.84 KB 22.03 KB 23.9 KB FB_WWW_DEV
react-jsx-dev-runtime.development.js +12.5% +8.1% 26.27 KB 29.56 KB 8.07 KB 8.72 KB NODE_DEV
react-jsx-dev-runtime.profiling.min.js 0.0% -0.3% 440 B 440 B 313 B 312 B NODE_PROFILING

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js +0.1% 0.0% 654.41 KB 654.82 KB 140.54 KB 140.6 KB RN_OSS_DEV
ReactNativeRenderer-prod.js 0.0% 0.0% 271.05 KB 271.08 KB 46.64 KB 46.65 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js 0.0% 0.0% 282.46 KB 282.51 KB 48.83 KB 48.83 KB RN_OSS_PROFILING
ReactFabric-dev.js +0.1% 0.0% 636.12 KB 636.53 KB 136.11 KB 136.16 KB RN_OSS_DEV
ReactFabric-prod.js 0.0% 0.0% 263.04 KB 263.07 KB 45.13 KB 45.13 KB RN_OSS_PROD
ReactFabric-profiling.js 0.0% 0.0% 274.45 KB 274.47 KB 47.32 KB 47.33 KB RN_OSS_PROFILING

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.production.min.js 0.0% 0.0% 119.63 KB 119.63 KB 37.5 KB 37.5 KB NODE_PROD
ReactDOMTesting-profiling.js 0.0% 0.0% 405.41 KB 405.44 KB 73.55 KB 73.56 KB FB_WWW_PROFILING
react-dom.profiling.min.js 0.0% 0.0% 123.51 KB 123.51 KB 38.63 KB 38.63 KB NODE_PROFILING
react-dom-test-utils.production.min.js 0.0% 0.0% 13.22 KB 13.22 KB 4.89 KB 4.89 KB UMD_PROD
react-dom-server.node.development.js -0.1% 0.0% 147.22 KB 147.14 KB 38.93 KB 38.93 KB NODE_DEV
react-dom-server.node.production.min.js 0.0% -0.0% 23.23 KB 23.23 KB 8.65 KB 8.65 KB NODE_PROD
ReactDOMForked-dev.js +0.5% +0.7% 1008.81 KB 1013.85 KB 223.65 KB 225.11 KB FB_WWW_DEV
ReactDOMForked-prod.js 🔺+0.4% 🔺+0.6% 422.64 KB 424.5 KB 76.08 KB 76.56 KB FB_WWW_PROD
react-dom-unstable-fizz.node.development.js 0.0% -0.1% 5.16 KB 5.16 KB 1.69 KB 1.69 KB NODE_DEV
react-dom.development.js +0.1% +0.1% 906.34 KB 907.09 KB 198.95 KB 199.11 KB UMD_DEV
ReactDOMForked-profiling.js +0.4% +0.6% 433.6 KB 435.46 KB 77.97 KB 78.45 KB FB_WWW_PROFILING
react-dom-server.browser.development.js -0.1% +0.1% 155.17 KB 155.09 KB 39.42 KB 39.44 KB UMD_DEV
react-dom.production.min.js 0.0% 0.0% 119.51 KB 119.51 KB 38.23 KB 38.23 KB UMD_PROD
react-dom.profiling.min.js 0.0% 0.0% 123.24 KB 123.25 KB 39.47 KB 39.48 KB UMD_PROFILING
ReactDOMTesting-dev.js 0.0% 0.0% 957.65 KB 958.06 KB 213.12 KB 213.18 KB FB_WWW_DEV
react-dom.development.js +0.1% +0.1% 862.81 KB 863.52 KB 196.51 KB 196.67 KB NODE_DEV
ReactDOMTesting-prod.js 0.0% 0.0% 405.41 KB 405.44 KB 73.55 KB 73.56 KB FB_WWW_PROD
react-dom-server.browser.development.js -0.1% 0.0% 146.01 KB 145.92 KB 38.67 KB 38.68 KB NODE_DEV
ReactDOM-dev.js +0.5% +0.7% 1008.79 KB 1013.83 KB 223.49 KB 224.96 KB FB_WWW_DEV
ReactDOMServer-dev.js +3.7% +4.4% 158.21 KB 164.1 KB 39.98 KB 41.73 KB FB_WWW_DEV
ReactDOM-prod.js 🔺+0.4% 🔺+0.6% 422.05 KB 423.91 KB 75.98 KB 76.46 KB FB_WWW_PROD
ReactDOMServer-prod.js 0.0% 🔺+0.1% 53.29 KB 53.3 KB 12.84 KB 12.85 KB FB_WWW_PROD
ReactDOM-profiling.js +0.4% +0.6% 433.01 KB 434.87 KB 77.89 KB 78.37 KB FB_WWW_PROFILING
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 56.1 KB 56.1 KB 13.84 KB 13.84 KB UMD_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.2% 1 KB 1 KB 608 B 609 B NODE_PROD
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 53.2 KB 53.2 KB 13.64 KB 13.64 KB NODE_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.1% +0.1% 576.93 KB 577.65 KB 122.08 KB 122.18 KB NODE_DEV
react-reconciler-reflection.development.js 0.0% 0.0% 16.22 KB 16.22 KB 4.91 KB 4.91 KB NODE_DEV
react-reconciler.production.min.js 0.0% -0.0% 77.1 KB 77.1 KB 22.84 KB 22.84 KB NODE_PROD
react-reconciler-reflection.production.min.js 0.0% 🔺+0.1% 2.57 KB 2.57 KB 1.08 KB 1.08 KB NODE_PROD

ReactDOM: size: 0.0%, gzip: 0.0%

Size changes (stable)

Generated by 🚫 dangerJS against ffc3006

@sizebot
Copy link

sizebot commented Apr 9, 2020

Details of bundled changes.

Comparing: af1b039...fbb0189

react

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react.development.js +4.4% +6.2% 105.81 KB 110.44 KB 25.41 KB 26.98 KB UMD_DEV
JSXRuntime-dev.js +31.7% +27.7% 29.38 KB 38.68 KB 8.61 KB 11 KB FB_WWW_DEV
react-jsx-dev-runtime.development.js +29.1% +24.9% 26.28 KB 33.93 KB 8.08 KB 10.09 KB NODE_DEV
JSXDEVRuntime-dev.js +32.3% +28.4% 28.79 KB 38.1 KB 8.43 KB 10.83 KB FB_WWW_DEV
react-jsx-runtime.development.js +28.5% +24.3% 26.87 KB 34.51 KB 8.25 KB 10.26 KB NODE_DEV
react.development.js +6.5% +8.7% 67.24 KB 71.62 KB 17.72 KB 19.25 KB NODE_DEV
React-dev.js +6.9% +8.6% 90.6 KB 96.85 KB 21.83 KB 23.71 KB FB_WWW_DEV
React-prod.js 0.0% 0.0% 17.16 KB 17.16 KB 4.49 KB 4.49 KB FB_WWW_PROD
React-profiling.js 0.0% 0.0% 17.16 KB 17.16 KB 4.49 KB 4.49 KB FB_WWW_PROFILING

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom-server.browser.development.js +2.9% +3.6% 156.76 KB 161.26 KB 39.62 KB 41.04 KB UMD_DEV
react-dom.profiling.min.js +0.4% +0.6% 127.77 KB 128.26 KB 39.87 KB 40.11 KB NODE_PROFILING
ReactDOM-dev.js +0.5% +0.7% 983.53 KB 988.57 KB 218.22 KB 219.72 KB FB_WWW_DEV
ReactDOM-prod.js 🔺+0.5% 🔺+0.7% 410.64 KB 412.5 KB 74.32 KB 74.82 KB FB_WWW_PROD
ReactDOM-profiling.js +0.4% +0.7% 421.54 KB 423.4 KB 76.17 KB 76.67 KB FB_WWW_PROFILING
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 4.43 KB 4.43 KB 1.55 KB 1.54 KB NODE_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% 🔺+0.2% 1.02 KB 1.02 KB 616 B 617 B NODE_PROD
react-dom-test-utils.development.js 0.0% 0.0% 75.14 KB 75.14 KB 20.11 KB 20.11 KB UMD_DEV
react-dom-test-utils.production.min.js 0.0% 0.0% 13.23 KB 13.23 KB 4.9 KB 4.9 KB UMD_PROD
ReactDOMTesting-dev.js 0.0% 0.0% 931.1 KB 931.52 KB 207.48 KB 207.54 KB FB_WWW_DEV
ReactDOMTesting-prod.js 0.0% 0.0% 393.59 KB 393.62 KB 71.77 KB 71.77 KB FB_WWW_PROD
ReactDOMTesting-profiling.js 0.0% 0.0% 393.59 KB 393.62 KB 71.77 KB 71.77 KB FB_WWW_PROFILING
react-dom-server.node.development.js +2.9% +3.5% 148.74 KB 153.02 KB 39.14 KB 40.52 KB NODE_DEV
react-dom-server.browser.development.js +2.9% +3.6% 147.52 KB 151.8 KB 38.88 KB 40.27 KB NODE_DEV
react-dom.development.js +0.4% +0.5% 936.26 KB 939.84 KB 204.24 KB 205.37 KB UMD_DEV
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 56.11 KB 56.11 KB 13.85 KB 13.85 KB UMD_DEV
react-dom.production.min.js 🔺+0.4% 🔺+0.6% 123.59 KB 124.06 KB 39.42 KB 39.64 KB UMD_PROD
ReactDOMForked-dev.js +0.5% +0.7% 983.55 KB 988.59 KB 218.37 KB 219.87 KB FB_WWW_DEV
ReactDOMServer-dev.js +3.8% +4.6% 154.71 KB 160.6 KB 39.04 KB 40.83 KB FB_WWW_DEV
react-dom.profiling.min.js +0.4% +0.6% 127.44 KB 127.91 KB 40.63 KB 40.87 KB UMD_PROFILING
ReactDOMForked-prod.js 🔺+0.5% 🔺+0.7% 411.21 KB 413.07 KB 74.41 KB 74.91 KB FB_WWW_PROD
ReactDOMServer-prod.js 0.0% 0.0% 52.56 KB 52.57 KB 12.68 KB 12.68 KB FB_WWW_PROD
react-dom.development.js +0.4% +0.6% 891.48 KB 894.89 KB 201.78 KB 202.89 KB NODE_DEV
ReactDOMForked-profiling.js +0.4% +0.7% 422.11 KB 423.97 KB 76.27 KB 76.77 KB FB_WWW_PROFILING
react-dom.production.min.js 🔺+0.4% 🔺+0.6% 123.78 KB 124.26 KB 38.62 KB 38.87 KB NODE_PROD

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js +0.5% +0.7% 653.58 KB 657.16 KB 137.19 KB 138.22 KB UMD_DEV
react-art.production.min.js 🔺+0.4% 🔺+0.7% 109.72 KB 110.19 KB 33.13 KB 33.35 KB UMD_PROD
react-art.development.js +0.6% +0.9% 557.13 KB 560.53 KB 119.67 KB 120.7 KB NODE_DEV
react-art.production.min.js 🔺+0.6% 🔺+1.0% 74.66 KB 75.14 KB 22.34 KB 22.57 KB NODE_PROD
ReactART-dev.js +0.9% +1.1% 589.88 KB 594.93 KB 123.81 KB 125.2 KB FB_WWW_DEV
ReactART-prod.js 🔺+0.8% 🔺+1.2% 241.12 KB 242.98 KB 40.78 KB 41.26 KB FB_WWW_PROD

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactTestRenderer-dev.js +0.1% 0.0% 576.86 KB 577.27 KB 121.74 KB 121.8 KB FB_WWW_DEV
react-test-renderer-shallow.production.min.js 0.0% -0.0% 12.74 KB 12.74 KB 3.97 KB 3.97 KB UMD_PROD
react-test-renderer.development.js +0.1% 0.0% 569 KB 569.44 KB 118.4 KB 118.45 KB UMD_DEV
react-test-renderer.production.min.js 0.0% 0.0% 74.15 KB 74.16 KB 22.55 KB 22.55 KB UMD_PROD
react-test-renderer.development.js +0.1% +0.1% 542.55 KB 542.97 KB 117.02 KB 117.1 KB NODE_DEV
react-test-renderer.production.min.js 0.0% 0.0% 73.95 KB 73.96 KB 22.24 KB 22.25 KB NODE_PROD

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-prod.js 0.0% 0.0% 271.07 KB 271.09 KB 46.65 KB 46.66 KB RN_OSS_PROD
ReactNativeRenderer-profiling.js 0.0% 0.0% 282.47 KB 282.53 KB 48.83 KB 48.84 KB RN_OSS_PROFILING
ReactFabric-prod.js 0.0% 0.0% 263.05 KB 263.08 KB 45.14 KB 45.14 KB RN_OSS_PROD
ReactFabric-profiling.js 0.0% 0.0% 274.46 KB 274.49 KB 47.33 KB 47.33 KB RN_OSS_PROFILING
ReactFabric-dev.js +0.1% +0.1% 640.62 KB 641.36 KB 136.86 KB 136.96 KB RN_FB_DEV
ReactFabric-prod.js 0.0% 0.0% 263.2 KB 263.23 KB 45.17 KB 45.18 KB RN_FB_PROD
ReactNativeRenderer-dev.js +0.1% 0.0% 654.42 KB 654.84 KB 140.55 KB 140.61 KB RN_OSS_DEV
ReactFabric-profiling.js 0.0% 0.0% 274.61 KB 274.63 KB 47.36 KB 47.37 KB RN_FB_PROFILING
ReactNativeRenderer-dev.js +0.1% +0.1% 658.9 KB 659.64 KB 141.3 KB 141.41 KB RN_FB_DEV
ReactNativeRenderer-prod.js 0.0% 0.0% 271.21 KB 271.24 KB 46.69 KB 46.69 KB RN_FB_PROD
ReactNativeRenderer-profiling.js 0.0% 0.0% 282.62 KB 282.67 KB 48.86 KB 48.87 KB RN_FB_PROFILING
ReactFabric-dev.js +0.1% 0.0% 636.13 KB 636.55 KB 136.11 KB 136.17 KB RN_OSS_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js +0.6% +0.8% 598.86 KB 602.26 KB 126.34 KB 127.35 KB NODE_DEV
react-reconciler.production.min.js 🔺+0.6% 🔺+1.1% 80.06 KB 80.54 KB 23.56 KB 23.82 KB NODE_PROD

Size changes (experimental)

Generated by 🚫 dangerJS against ffc3006

@sebmarkbage sebmarkbage force-pushed the proderrorstacks branch 6 times, most recently from 97fac34 to d7a16ff Compare April 10, 2020 04:44
@sebmarkbage sebmarkbage marked this pull request as ready for review April 10, 2020 05:06
ReactDebugCurrentFrame.setCurrentlyValidatingElement = function(
element: null | ReactElement,
) {
ReactDebugCurrentFrame.setExtraStackFrame = function(stack: null | string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit could just assign:
ReactDebugCurrentFrame.setExtraStackFrame = setExtraStackFrame;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's DEV it probably doesn't matter but in general that might not be great because one is meant to be called in this same package so it can be inlined. So that would avoid inlining it.

@@ -7,26 +7,20 @@
* @flow
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The organization of this file is confusing to me.

  1. We unconditionally export a setter which sets a variable that is not exported (and has no getter or is otherwise unused except for DEV mode which uses it in getStackAddendum).
  2. We assign a duplicate of that same setter to ReactDebugCurrentFrame in DEV mode, but we don't assign a getter. We leave that up to the current renderer, which of course, doesn't even use the local value written by ReactDebugCurrentFrame.setExtraStackFrame because it has no way to access it. So instead it uses its own local current fiber value.

Looks like the only thing using the exported setCurrentlyValidatingElement function (now setExtraStackFrame) is ReactElementValidator - and even it only uses it in DEV. So why are we using this odd pattern?

I'm not super familiar with some of these files so maybe there's a subtle difference that I'm overlooking.

Suggestion: Update ReactElementValidator to use ReactDebugCurrentFrame.* too, then get rid of the ES export.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's complicated because this is used by jsx-runtime too which is a separate file that needs to import this from isomorphic. This needs some further refactoring in a follow up at some point.

For now I'm just removing a cycle that otherwise would break.

if (__DEV__) {
setCurrentlyValidatingElement(element);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. I noticed this while writing my above comment.

// $FlowFixMe Flow thinks console is immutable.
console.error = prevError;
/* eslint-enable react-internal/no-production-logging */
disabledDepth--;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we throw or warn if we ever go < 0?


describe('Component stack trace displaying', () => {
beforeEach(() => {
React = require('react');
ReactDOM = require('react-dom');
});

if (ReactFeatureFlags.enableComponentStackLocations) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look necessary (at least not yet?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll just remove this test later. It's not very useful for this model. This test fails with the stack on, partly because the warning gets deduped because it's always the same component and line being called.

// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
const frame = '\n' + sampleLines[s - 1].replace(' at new ', ' at ');
if (__DEV__) {
if (typeof fn === 'function') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this typeof check necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it throws in WeakMap if the wrong type sneaks in. That kills the stack which is not good if we're warning because some wrong type. We have tests that cover that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. It looked odd to have fn: Function followed by a typeof check.

In DEV it's somewhat likely that we'll see many logs that add component
stacks. This could be slow so we cache the results of previous components.
In V8 we need to ignore the first line. Normally we would never get there
because the stacks would differ before that, but the stacks are the same if
we end up throwing at the same place as the control.
This drops the requirement to include owner to pass the test.
This ensures that we don't double call yieldValue or advanceTime in tests.

Ideally we could use empty destructuring but ES lint doesn't like it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants