Can you catch all React.js application errors with a try / catch block?

I made a responsive application that doesn’t work live, and the people who use it note that some strange error sometimes happens. I do not know why and what is happening, and I can not reproduce it.

So I'm wondering if there is a way to wrap the entire application or parts of it in a try / catch block so that I can send errors to the error log on the server?

All I have read so far is that you can wrap the entire rendering function in try / catch, but that will not lead to errors due to proper user intervention?

+8
try-catch reactjs
source share
3 answers

this is what i ended up using

componentWillMount: function () { this.startErrorLog(); } startErrorLog:function() { window.onerror = (message,file,line,column,errorObject) => { column = column || (window.event && window.event.errorCharacter); var stack = errorObject ? errorObject.stack : null; //trying to get stack from IE if(!stack) { var stack = []; var f = arguments.callee.caller; while (f) { stack.push(f.name); f = f.caller; } errorObject['stack'] = stack; } var data = { message:message, file:file, line:line, column:column, errorStack:stack, }; //here I make a call to the server to log the error //the error can still be triggered as usual, we just wanted to know what happening on the client side return false; } } 
+17
source share

You can use the React BatchingStrategy API to easily wrap try/catch around all your React code. The advantage of this over window.onerror is that you get a good stack trace in all browsers. Even modern browsers such as Microsoft Edge and Safari do not provide stack traces to window.onerror .

Here's what it looks like in React 15.4:

 import ReactUpdates from "react-dom/lib/ReactUpdates"; import ReactDefaultBatchingStrategy from "react-dom/lib/ReactDefaultBatchingStrategy"; let isHandlingError = false; const ReactTryCatchBatchingStrategy = { // this is part of the BatchingStrategy API. simply pass along // what the default batching strategy would do. get isBatchingUpdates () { return ReactDefaultBatchingStrategy.isBatchingUpdates; }, batchedUpdates (...args) { try { ReactDefaultBatchingStrategy.batchedUpdates(...args); } catch (e) { if (isHandlingError) { // our error handling code threw an error. just throw now throw e; } isHandlingError = true; try { // dispatch redux action notifying the app that an error occurred. // replace this with whatever error handling logic you like. store.dispatch(appTriggeredError(e)); } finally { isHandlingError = false; } } }, }; ReactUpdates.injection.injectBatchingStrategy(ReactTryCatchBatchingStrategy); 

Full entry here: https://engineering.classdojo.com/blog/2016/12/10/catching-react-errors/

+15
source share

I had the same problem. I created an Office application in which I did not have a console for debugging or developer tools, so I could not find out where the errors occurred.

I created one component (es6 class) that hooked all the console messages, saved the message in a separate array, and called the "real" console function.

 log(message) { const msg = new Log(message); this.pushMessage(msg); this._target.log(message); } 

where Log is a simple wrapper with message and a type and this._target is a link to window.console . So I did the same with info , warn and error .

In addition, I created the handleThrownErrors(message, url, lineNumber) method to detect exceptions.

 window.onerror = this.handleThrownErrors.bind(this); 

At least I created an instance of the class (I named it LogCollector ) and added it to the window.

 window.logCollector = new LogCollector(); 

Now I have created a reaction component that receives an instance of logCollector ( window.logCollector ) as a property. At regular intervals, the reacting component checks the collected messages and displays them on the screen.

 componentDidMount() { this.setInterval(this._forceUpdate, 500); }, _forceUpdate() { this.setState({update: !this.state.update}); } 

this.setInterval() is a native function that simply calls window.setInterval() .

And in the render() method:

 return ( <div class="console"> {this.props.logCollector.getMessages().map(this.createConsoleMessage)} </div> ); 

NOTE It is important to include LogCollector before all other files.

NOTE The above solution is a very simplified version. For example: you can improve it by adding custom (message-) listeners or by catching 404 Not found errors (for js-scripts and css files).

+2
source share

All Articles