Flion Flion - 3 months ago 15
React JSX Question

can you catch all errors of a React.js app with a try/catch block?

I've made a react application which is not running live, and the people that use it note that very occasionally some strange error occurs. I don't know why or what happens, and can't reproduce it.

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

All I've read so far is that you could wrap the entire render function in a try/catch, but that would not catch any errors due to user interation right?

Answer

I had the same problem. I created an Office App where I neither had a debug console nor developer tools, so I couldn't found out where errors occured.

I created a single component (an es6-class) that catched all console messages, saved the message into 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 a message and a type and this._target is a reference on window.console. So I did the same with info, warn and error.

Additionally, I created a method handleThrownErrors(message, url, lineNumber) to catch exceptions.

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

At least I created an instance of the class (i called it LogCollector) and appended it to the window.

window.logCollector = new LogCollector();

Now I created an react component that gets the logCollector instance (window.logCollector) as property. In regular intervals the react component checks the collected messages and display them on the screen.

componentDidMount() {
    this.setInterval(this._forceUpdate, 500);
},

_forceUpdate() {
    this.setState({update: !this.state.update});
}

this.setInterval() is an own function that simply calls window.setInterval().

And in render() method:

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

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

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