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

Error Overlay Shows Un-Source-Mapped Lines #226

Open
machineghost opened this issue Oct 12, 2020 · 7 comments
Open

Error Overlay Shows Un-Source-Mapped Lines #226

machineghost opened this issue Oct 12, 2020 · 7 comments

Comments

@machineghost
Copy link

machineghost commented Oct 12, 2020

I'm using this plugin with the following config (irrelevant parts omitted):

// Using source maps (specifically the slow but good kind) 
devtool: 'eval-source-map',

plugins: [
   new webpack.HotModuleReplacementPlugin(),
   // Using this plug-in, along with other plug-ins, as I believe is normal
   new ReactRefreshPlugin({
     overlay: {
       sockIntegration: 'whm',
     },
   }),
   new HtmlWebpackPlugin({
     filename: './index.html',
     template: './public/index.html',
   }),
],

When I get an error, in the error overlay I see line numbers from the webpack-generated source code ... not the source-mapped line numbers:

TypeError
Cannot read property 'id' of undefined
Call Stack
 eval
  client/src/hooks/mutations/useAddFoo.js:41:38
 asyncGeneratorStep
  client/src/hooks/mutations/useAddFoo.js:9:103
 _next
  client/src/hooks/mutations/useAddFoo.js:11:194

But in my console I can see the correct (ie. source-mapped) line numbers:

useAddFoo.js?fda8:23 Uncaught (in promise) TypeError: Cannot read property 'id' of undefined
at eval (useAddFoo.js?fda8:23)
at Generator.next ()
at asyncGeneratorStep (useAddFoo.js:9)
at _next (useAddFoo.js:11)

It seems to me Webpack knows what source map approach I'm taking ... and so this plugin ought to be able to also?

P.S. I don't think it matters, but this is all through the Webpack dev server middleware, not the standalone Webpack.

@pmmmwh
Copy link
Owner

pmmmwh commented Oct 18, 2020

Hi, can you provide a bit more insight what browsers you're running on? This most likely are related to how we consume webpack call stacks currently, but might be also caused by discrepancies between browsers' interpretation of sources and webpack's source maps.

@machineghost
Copy link
Author

machineghost commented Oct 18, 2020

Google Chrome, latest version: 86.0.4240.75 (Official Build) (64-bit)

That's on Linux ... but I'd be surprised if Linux Chrome handles source maps differently from (say) Mac Chrome, as both are *nix.

@machineghost
Copy link
Author

Is there any further data I can provide?

@bdanzer
Copy link

bdanzer commented Jan 1, 2021

To add to this, and admittedly I am not sure if I am doing something wrong so if there is a way to display better error messages please let me know. But I've also noticed the error messages I get while developing are not usually helpful. Compared to create react app, I can click on the error message and it will take me to the spot where I errored in my code in my editor. It does seem like I get pointed to the webpack bundle in most cases where my error is and even setting dev-tool: 'eval-source-map' doesn't seems to resolve this. Here is an example:

In my code I did this:

function TestComponent() {
    const forceError = {key: "value"}
    return <div>{forceError}</div>
}

Which will force and error like this on this overlay:

image

vs create react app:

image

It doesn't show me the exact code but it does get the line number correct on where my error is. In the first one it shows what file the error occurred in but not the correct line number. It only shows the line number of the compiled code even with dev-tool: 'eval-source-map'. I am using MacOS as well.

Maybe this package should support this? https://www.npmjs.com/package/react-error-overlay Or maybe allow for someway to change the error overlay so it can be swapped out.

@pmmmwh
Copy link
Owner

pmmmwh commented Jan 2, 2021

OK, so let me address this properly.

This issue is only addressing RUNTIME errors (i.e. when the browser executes code, not when Webpack compiles).

For runtime errors, this behaviour as of now, is the INTENDED behaviour. It is not perfect, it is not pretty and it is not the best experience, but it is always correct - as we directly consume the error object thrown in the browser, and map out the stacks as is. Yes, even if you provide source maps, the error stacks thrown by the browser are still pointing to the un-mapped sources.

So how does others achieve their experience? Well, turns out the "good" error overlays does an extra step - fetches your source map and enhances the stack traces with their original locations. For that to work, CRUTIAL assumptions are needed to be satisfied:

react-error-overlay

  • Utilises custom webpack-dev-server middleware to provide jump-to-editor support
  • Utilises custom webpack-dev-server middleware for source maps
  • ENFORCES the usage of cheap-module-source-map - doesn't work otherwise
  • Constrained ways of fetching source maps (fixed paths basically), does not work well with custom paths and servers under proxies

@next/react-dev-overlay

  • Utilises a global error boundary which wraps the app
  • Utilises custom middlewares to serve source-mapped stack traces
  • Utilises constrained file paths (_next) to fetch source maps
  • ENFORCES the usage of only certain source maps - doesn't work well with others

For us, these assumptions are simply too strict - we support multiple Webpack socket integrations with custom paths and servers under proxies, we do not have a constrained file system, we cannot inject middleware in users' setup, etc.

If we needed to properly support source-mapped error stack traces, we would have to:

  1. Ensure the baseline experience works, even without source maps.
  2. Implement a way to get source map paths from a file's content, which probably would include parsing the current execution context and parsing Webpack's compiled source somehow.
  3. Implement a type-agnostic method to fetch source maps. This have to support multi-compiler scenarios, micro-frontend use cases and more.
  4. Implement means to enhance stack traces with the fetched source maps, and fallback to raw stacks if they aren't available.
  5. Support IE11 out-of-the-box, which basically means we probably need to polyfill Promises.

As for React component stacks, they are not officially supported by React in any means (CRA is using a very stripped down proposal of the console.stack proposal to get that working for invalid element type errors only). I'm pushing for React to expose the information to third party integrations, but until that happens we can only wait.

I would love to make the experience much better, but in the end I have not implemented this because of the shear amount of R&D and API-surface to cover. It is still on my radar and I would love to work on it, but until all other more important issues are fleshed out (like bugs in the actual refresh runtime) I probably wouldn't touch this - PRs are always welcomed though :)

@pmmmwh
Copy link
Owner

pmmmwh commented Jan 2, 2021

Maybe this package should support this? npmjs.com/package/react-error-overlay Or maybe allow for someway to change the error overlay so it can be swapped out.

You can always use the overlay parameter to swap out the overlay. In fact it is exactly what we do in create-react-app

https://github.com/facebook/create-react-app/blob/282c03f9525fdf8061ffa1ec50dce89296d916bd/packages/react-scripts/config/webpack.config.js#L649-L661

However, if you want to use react-error-overlay you would have to ensure that all the constraints I mentioned above are satisfied.

Their middleware setup:

https://github.com/facebook/create-react-app/blob/282c03f9525fdf8061ffa1ec50dce89296d916bd/packages/react-scripts/config/webpackDevServer.config.js#L113-L136

@Jma353
Copy link

Jma353 commented Aug 19, 2023

@pmmmwh -- I was wondering if you had a vetted workaround here to wire up a different overlay to resolve this issue. I fiddled with a couple of different options listed but couldn't get settings to line up to get proper source-map support working with this plugin.

Thanks in advance for any help here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants