import React from 'react'; /** * A default ErrorBoundary that renders children, or if they produce an error, renders the passed * onError() function, optionally with the error as a prop. */ export class GlobalSentryBoundary extends React.Component { state = { reactError: undefined }; componentDidCatch(error, errorInfo) { this.handleError(error, errorInfo); } componentWillMount() { // handle global errors that happens in events, etc. window.onerror = (message, file, lineNo, columnNo, error) => { if (error) { this.handleError(error); // return true here to prevent firing the default event handler return; } // some browsers like Edge don't supply the last error argument const errorMessage = JSON.stringify({ message, file, lineNo, columnNo, }); this.handleError(new Error(errorMessage)); // return true here to prevent firing the default event handler }; // handle async errors // as of 15/08/18 some major browsers are still not supporting this: https://caniuse.com/#feat=unhandledrejection window.onunhandledrejection = this.handleError; } handleError = (error, errorInfo) => { if (!errorInfo) { errorInfo = { componentStack: 'The error did not happen in a React component lifecycle - Component stack not available.', }; } // set state to force re-render to error-view this.setState({ reactError: { error, errorInfo } }); // do more error handling here like logging, monitoring, etc. // ... }; render() { if (this.state.reactError && this.props.onError) { return this.props.onError(this.state.reactError); } return this.props.children; } }