react: Cross-origin error passed to componentDidCatch incorrectly

tl;dr React is passing “A cross-origin error was thrown” to componentDidCatch when there are no cross-origin scripts.

See this discussion thread and this repro case.

I was able to confirm the behavior. A quick look at onError showed a null event.error.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 3
  • Comments: 59 (25 by maintainers)

Commits related to this issue

Most upvoted comments

Same issue here with Windows 10, Chrome 62, Webpack 3 & React 16.0-16.1.

Webpack+React always throws Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development..


Tried devtool: 'cheap-module-source-map' (and others without eval)


Tried

devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
    },
}

Tried

output: {
  crossOriginLoading: 'anonymous',
}

Tried crossorigin script tag


Nothing works

FYI @leidegre the solution for this issue is to replace:

devtool: "eval"

with:

devtool: "cheap-module-source-map"

in your Webpack config.

For what it’s worth, I ran through the all of the devtools settings and here’s what I found:

devtool works?
default
eval
cheap-eval-source-map
cheap-source-map
cheap-module-eval-source-map
cheap-module-source-map
eval-source-map
source-map
inline-source-map
hidden-source-map
nosources-source-map

It looks like the default setting (and any of the *eval ones) will cause problems.

We can probably encourage people to stop using it and use cheap-module-source-map instead. It’s just as fast (afaik) and doesn’t have some issues.

Looks like the repro case (starting with the tessin_mini repo) can be reduced to:

import React, { Component } from "react";

export default class App extends Component {
  state = {
    doError: false,
  };

  render() {
    return (
      <ErrorBoundary>
        {this.state.doError
          ? <ComponentThatFails/>
          : <button onClick={() => this.setState({doError: true})}>Click me</button>}
      </ErrorBoundary>
    )
  }
}

class ErrorBoundary extends Component {
  state = {
    error: null
  };

  componentDidCatch(error) {
    this.setState({error})
  }

  render() {
    if (this.state.error) {
      return this.state.error.message;
    }
    return this.props.children
  }
}

class ComponentThatFails extends Component {
  render() {
    const data = null;
    return <p>{data.foo}</p>;
  }
}

The console will log:

Uncaught TypeError: Cannot read property ‘foo’ of null

But the error we pass to componentDidCatch will be:

A cross-origin error was thrown…

Experiencing same problem in Chrome, nothing works as @DominikSerafin mentioned, but there is no such error in Firefox.

Following solution works for me:

webpack.config.js

devServer: {
    headers: {
        'Access-Control-Allow-Origin': '*'
    }
}

package.json

"start": "webpack-dev-server --devtool source-map --history-api-fallback --hot"

And crossorigin on script tag.

I’m still getting this as well no matter my webpack settings.

Same thing for me as for @the-spyke, eval is much faster than other alternatives in my project(s).

React should work correctly with it, and not suggest workarounds (which do not even work).

Hoping it will get fixed…

The team chatted out of band about this briefly and the agreed-upon solution is to change the wording of the error message passed to componentDidCatch to be:

A cross-origin error was thrown so React doesn’t have access to the actual error object in development. See https://fb.me/react-crossorigin-error for more details.

At the specified URL we’ll have a blurb that explains the technique we’re using in dev-mode and mentions both the <script> tag crossorigin attribute for CDNs and the Webpack devtools setting.

Please, make an option for disable this behavior. I want to use eval (performance, compatibility). And if switch to a cheap-module-source-map, I just get a duplicate error in the console.

Updated dependencies today and started to get this issue in tests. Not sure what is just as fast, but in my project eval is 2-3 times faster in rebuilds by webpack-dev-server watch.

No worries. If people are still seeing it, it’s probably okay to re-open it. 😄

@bvaughn @gaearon So I’m just super happy that we could root cause this, thanks for the hard work! Enjoy your weekend!

I had to do these 3 things together (using webpack-dev-server running on port 8080):

Add this to webpack config:

devServer: {
    headers: {
        'Access-Control-Allow-Origin': '*'
    }
}

use cheap-module-source-map (cheap-module-eval-source-map did not work)

Add crossorigin to my script tag:

<script crossorigin src="http://localhost:8080/public/bundle.js"></script>

@bvaughn

Sure, here is a simple demo project: https://github.com/jjjjw/crossorigin-webpack-demo

Worth noting that the case is when webpack dev server is used on a different port/domain than the web server.

Additionally, here is a first go at a doc addition: https://github.com/reactjs/reactjs.org/pull/187

I ran into this problem when using webpack, code splitting, and webpack dev server (similar to a CDN setup).

In my setup the initial bundle is loaded with a script tag, and other bundles are then loaded via JSONP by webpack. With the crossorigin attribute added to the script tag for the initial bundle errors can be handled, but only if they are thrown by code in the initial bundle.

To handle errors in the other bundles it’s necessary to configure webpack for crossorigin script loading with this option https://webpack.js.org/configuration/output/#output-crossoriginloading

Like so in the webpack config:

  ...  
  output: {
    crossOriginLoading: 'anonymous',
    ...
  }

This adds the crossorigin attribute to the JSONP script tags used to load the bundles.

I’ll put up a PR that adds addition verbiage to the cross-origin (dev-mode) error to mention this.

Creating a small, standalone project with no SSR/Webpack/etc, I am able to reproduce the unexpected behavior only for Chrome when loading content via file://....

Here’s what I’m seeing:

Browser standalone file:// standalone http:// tessin_mini dev tessin_mini prod
Chrome 1 2
Firefox
Safari

1: I believe Chrome considers files loaded with file:// to always be a different domain. If I launch Chrome with the --allow-file-access-from-files flag, the standalone file works with when loaded via the file:// protocol as well.

2: Also worth adding that the tessin_mini example works as expected in production mode (b’c we use a regular try/catch). The unexpected cross-origin error only affects dev-mode.

After getting stuck on this for several days, we tried all kinds of solutions but to no avail. In the end, we found out that 127.0.0.1 and localhost are cross-origin, e.g. serving the app via 127.0.0.1 but visiting it via localhost will trigger this issue, hope that helps.

Want to highlight, similarly to @programmerwy, that it started working for me, even with the source map set to eval-source-map, once I added crossorigin to the script tag that loads the webpack bundle (couldn’t get it to work no matter what without that attribute on the script tag).

Using Chrome 80.0.3987.100 (Linux) and React 16.12.

Try checking your package.json, remove the -d flag.

That’s what finally worked for me.

I’ve noticed that I have this issue when Chrome DevTools are open, crossOriginLoading and devtool = cheap-module-source-map doesn’t change anything. Works fine in Firefox with open developer tools.

@bvaughn, my project is buggy. Sorry for flooding this thread. To whom it may concern, here’s a minimal setup of a Chrome extension using React, Redux, react-devtools and error boundaries.

Source: https://github.com/herodrigues/chrome-react-minimal

ezgif com-crop

I am using cheap-module-source-map, but the error is thrown twice. Does anyone know what it could be?

What makes you say the error is thrown twice?

Are you referring to what Dan describes in facebook/react/issues/10384, by chance?

Same problem here, tried both crossOriginLoading: ‘anonymous’ and devtool set to ‘cheap-module-eval-source-map’

You’re welcome @leidegre!

Just to close the loop here, we’ve added a new docs page with information about this and other cross-origin error causes:

https://fb.me/react-crossorigin-error

By eval I meant the Webpack devtool: "eval" setting which is commonly used and turns every module into eval call so that it’s shown separately in DevTools despite no sourcemaps. But seems like we determined that isn’t the issue.