<p dir="auto"><strong>Do you want to request a <em>feature</em> or report a <em>bug</em>?</strong></p>
<p dir="auto">bug</p>
<p dir="auto"><strong>What is the current behavior?</strong></p>
<p dir="auto">Error event fired twice when in development mode.</p>
<p dir="auto">In the example you can see that '&gt;&gt;&gt;&gt;&gt;&gt;error' is logged twice while I only expect to see it once.</p>
<p dir="auto">Note: this issue doesn't happen with the production version of react</p>
<p dir="auto"><strong>If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (<a href="https://jsfiddle.net/Luktwrdm/" rel="nofollow">https://jsfiddle.net/Luktwrdm/</a>) or CodeSandbox (<a href="https://codesandbox.io/s/new" rel="nofollow">https://codesandbox.io/s/new</a>) example below:</strong></p>
<ul dir="auto">
<li>codepen demo:<br>
<a href="https://codepen.io/anon/pen/ppXZXP?editors=0011" rel="nofollow">https://codepen.io/anon/pen/ppXZXP?editors=0011</a></li>
</ul>
<p dir="auto">static html reproducing the problem:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;title&gt;Hello World&lt;/title&gt;
    &lt;script src=&quot;https://unpkg.com/react@16/umd/react.development.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://unpkg.com/react-dom@16/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://unpkg.com/babel-standalone@6.15.0/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
    &lt;script type=&quot;text/babel&quot;&gt;

      function handleErr(event){
        console.log('&gt;&gt;&gt;&gt;&gt;&gt;error')
      }

      window.addEventListener('error', handleErr);

      function onClick (e) {
        e.stopPropagation()
        e.preventDefault()
        throw new Error('-------------');
      }

      ReactDOM.render(
        &lt;button onClick={onClick}&gt;button&lt;/button&gt;,
        document.getElementById('root')
      );

    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;"><pre class="notranslate"><code class="notranslate">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;title&gt;Hello World&lt;/title&gt;
    &lt;script src="https://unpkg.com/react@16/umd/react.development.js"&gt;&lt;/script&gt;
    &lt;script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"&gt;&lt;/script&gt;
    &lt;script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
    &lt;script type="text/babel"&gt;

      function handleErr(event){
        console.log('&gt;&gt;&gt;&gt;&gt;&gt;error')
      }

      window.addEventListener('error', handleErr);

      function onClick (e) {
        e.stopPropagation()
        e.preventDefault()
        throw new Error('-------------');
      }

      ReactDOM.render(
        &lt;button onClick={onClick}&gt;button&lt;/button&gt;,
        document.getElementById('root')
      );

    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre></div>
<p dir="auto"><strong>What is the expected behavior?</strong></p>
<p dir="auto">I expect to see '&gt;&gt;&gt;&gt;&gt;&gt;error' logged once</p>
<p dir="auto"><strong>Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?</strong></p>
<p dir="auto">reproduced on:</p>
<p dir="auto">react v16.2.0<br>
Chrome 63.0.3239.132<br>
OSX 10.10.5</p>
<p dir="auto">I'm trying to make use of componentDidCatch in the React 16 beta. I already had a global window error handler which was working fine, but it unexpectedly catches errors that I would expect componentDidCatch to have handled. That is, component-local errors are being treated as window-global errors in dev builds.</p>
<p dir="auto">The problem seems to stem from <code class="notranslate">invokeGuardedCallbackDev</code> in <code class="notranslate">ReactErrorUtils.js</code>. I think that this entire <code class="notranslate">__DEV__</code> block of code is problematic. The stated rational is:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  // In DEV mode, we swap out invokeGuardedCallback for a special version
  // that plays more nicely with the browser's DevTools. The idea is to preserve
  // &quot;Pause on exceptions&quot; behavior. Because React wraps all user-provided
  // functions in invokeGuardedCallback, and the production version of
  // invokeGuardedCallback uses a try-catch, all user exceptions are treated
  // like caught exceptions, and the DevTools won't pause unless the developer
  // takes the extra step of enabling pause on caught exceptions. This is
  // untintuitive, though, because even though React has caught the error, from
  // the developer's perspective, the error is uncaught."><pre class="notranslate"><code class="notranslate">  // In DEV mode, we swap out invokeGuardedCallback for a special version
  // that plays more nicely with the browser's DevTools. The idea is to preserve
  // "Pause on exceptions" behavior. Because React wraps all user-provided
  // functions in invokeGuardedCallback, and the production version of
  // invokeGuardedCallback uses a try-catch, all user exceptions are treated
  // like caught exceptions, and the DevTools won't pause unless the developer
  // takes the extra step of enabling pause on caught exceptions. This is
  // untintuitive, though, because even though React has caught the error, from
  // the developer's perspective, the error is uncaught.
</code></pre></div>
<p dir="auto">This is misguided because it's not about pausing on exceptions, it's about "pause on <em>uncaught</em> exceptions." However, <code class="notranslate">componentDidCatch</code> makes exceptions <em>caught</em>!</p>
<p dir="auto">Rather than switching on prod vs dev and using try/catch in prod and window's error handler in dev, React should always use try/catch, but rethrow if you reach the root without hitting a componentDidCatch handler. This would preserve the correct "pause on uncaught exceptions" behavior without messing with global error handlers.</p>