Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 937
Flion Avatar asked Jun 29 '15 09:06

Flion


People also ask

How do you catch errors in Reactjs?

Error boundaries were introduced in React 16 as a way to catch and handle JavaScript errors that occur in the UI parts of our component. So error boundaries only catch errors that occur in a lifecycle method, render method, and inside Hooks like useEffect .

Can I use try catch in React?

catch statement can be used to catch JavaScript errors in React components. This is because the try... catch statement only works for imperative code, as opposed to the declarative code we have in components. This error fallback UI has been clipped to show the relevant part.

Which errors Cannot be handled by catch block?

As is documented, try/catch blocks can't handle StackOverflowException and OutOfMemoryException.

Does try catch stop errors?

The “try… First, the code in try {...} is executed. If there were no errors, then catch (err) is ignored: the execution reaches the end of try and goes on, skipping catch . If an error occurs, then the try execution is stopped, and control flows to the beginning of catch (err) .


2 Answers

React 16 introduced Error Boundaries and the componentDidCatch lifecycle method:

class ErrorBoundary extends React.Component {   constructor(props) {     super(props);     this.state = { hasError: false };   }    componentDidCatch(error, info) {     // Display fallback UI     this.setState({ hasError: true });     // You can also log the error to an error reporting service     logErrorToMyService(error, info);   }    render() {     if (this.state.hasError) {       // You can render any custom fallback UI       return <h1>Something went wrong.</h1>;     }     return this.props.children;   } } 

Then you can use it as a regular component:

<ErrorBoundary>   <MyWidget /> </ErrorBoundary> 

Or you can wrap your root component with the npm package react-error-boundary, and set a fallback component and behavior.

import {ErrorBoundary} from 'react-error-boundary';  const myErrorHandler = (error: Error, componentStack: string) => {   // ... };  <ErrorBoundary onError={myErrorHandler}>   <ComponentThatMayError /> </ErrorBoundary> 
like image 54
goldylucks Avatar answered Sep 29 '22 15:09

goldylucks


this is what I ended up using

EDIT: React 16 introduced proper ways to do this, see @goldylucks answer.

  componentWillMount() {     this.startErrorLog();   }    startErrorLog() {     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's happening on the client side       return false;     };   } 
like image 25
Flion Avatar answered Sep 29 '22 15:09

Flion