Spaces:
Running
Running
File size: 2,194 Bytes
6bcb42f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import React from 'react';
import PropTypes from 'prop-types';
import CrashMessageComponent from '../components/crash-message/crash-message.jsx';
import log from '../lib/log.js';
import {recommendedBrowser} from '../lib/supported-browser';
class ErrorBoundary extends React.Component {
constructor (props) {
super(props);
this.state = {
hasError: false,
errorId: null
};
}
componentDidCatch (error, info) {
// Error object may be undefined (IE?)
error = error || {
stack: 'Unknown stack',
message: 'Unknown error'
};
// Log errors to analytics, leaving out browsers that are not in our recommended set
if (recommendedBrowser() && window.Sentry) {
window.Sentry.withScope(scope => {
Object.keys(info).forEach(key => {
scope.setExtra(key, info[key]);
});
scope.setExtra('action', this.props.action);
window.Sentry.captureException(error);
});
}
// Display fallback UI
this.setState({
hasError: true,
errorId: window.Sentry ? window.Sentry.lastEventId() : null,
errorMessage: `${(error && error.message) || error}`
});
// Log error locally for debugging as well.
log.error(`Unhandled Error: ${error.stack ? error.stack : error}\nComponent stack: ${info.componentStack}`);
}
handleBack () {
window.history.back();
}
handleReload () {
window.location.replace(window.location.origin + window.location.pathname);
}
render () {
if (this.state.hasError) {
return (
<CrashMessageComponent
eventId={this.state.errorId}
errorMessage={this.state.errorMessage}
onReload={this.handleReload}
/>
);
}
return this.props.children;
}
}
ErrorBoundary.propTypes = {
action: PropTypes.string.isRequired, // Used for defining tracking action
children: PropTypes.node
};
export default ErrorBoundary;
|