How do I handle exceptions?

2019-04-06 15:11发布

问题:

Angular has a great $exceptionHandler. Is there anything like this for react.js?

I would like to log my errors to an external API. Examples:

  • https://github.com/occ/TraceKit
  • http://trackjs.com/
  • https://plus.google.com/+PaulIrish/posts/12BVL5exFJn

回答1:

There's no magic like in angular. If there's an uncaught error, it propagates up the scopes until it hits window, and then an error event is emitted – the same behavior as an error without react.

var App = React.createClass({
  render: function(){
    throw new Error("rawr!");
    return <div>Hello, world!</div>
  }
});

window.addEventListener('error', function(e){
  // e instanceof ErrorEvent
  console.error('caught the error: ' + e.message);
});

If you look into cross browser support, please update this answer or add a comment with citations.

Instead of logging it to the console (which already happens by default), you can send it anywhere you like.

Unlike some other frameworks, an uncaught error is always a bug in your code. It should never happen.

You may also need to do some special handling of promise errors by explicitly adding a .catch(reportError) to the end of chains, and checking that it's a TypeError or ReferenceError.



回答2:

While @FakeRainBrigand's answer gives a very good starting point in understanding the mechanism of general 'uncaught error' reporting mechanism in Javascript, I feel most of apps host their JS bundles using CDNs where you just can't capture uncaught errors with "window.addEventListener('error', fn)" mechanism.

Get around crossorigin limitations

Put crossorigin attribute to your script tag so that you can enjoy catching uncaught errors with "window.addEventListener('error', fn)" mechanism.

In cases where you just can't get around with cors settings

React 16: provides built-in Error handling mechanism. Read more about Error Boundaries in React here

React 15 or below: Only way to catch errors here is via adding try-catch blocks around every renders/components. Luckily we have an npm module - react-guard which does exactly that for us by patching React.