Spaces:
Runtime error
Runtime error
File size: 2,655 Bytes
8fd7a1d |
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
import React from 'react';
import PropTypes from 'prop-types';
import CrashMessageComponent from '../components/crash-message/crash-message.jsx';
import log from '../lib/log.js';
class ErrorBoundary extends React.Component {
constructor (props) {
super(props);
this.state = {
error: null,
errorInfo: null
};
}
/**
* Handle an error caught by this ErrorBoundary component.
* @param {Error} error - the error that was caught.
* @param {React.ErrorInfo} errorInfo - the React error info associated with the error.
*/
componentDidCatch (error, errorInfo) {
// Error object may be undefined (IE?)
error = error || {
stack: 'Unknown stack',
message: 'Unknown error'
};
errorInfo = errorInfo || {
componentStack: 'Unknown component stack'
};
// only remember the first error: later errors might just be side effects of that first one
if (!this.state.error) {
// store error & errorInfo for debugging
this.setState({
error,
errorInfo
});
}
// report every error in the console
log.error([
`Unhandled Error with action='${this.props.action}': ${error.stack}`,
`Component stack: ${errorInfo.componentStack}`
].join('\n'));
}
handleBack () {
window.history.back();
}
handleReload () {
window.location.replace(window.location.origin + window.location.pathname);
}
formatErrorMessage () {
let message = '';
if (this.state.error) {
message += `${this.state.error}`;
} else {
message += 'Unknown error';
}
if (this.state.errorInfo) {
const firstCoupleLines = this.state
.errorInfo
.componentStack
.trim()
.split('\n')
.slice(0, 2)
.map(i => i.trim());
message += `\nComponent stack: ${firstCoupleLines.join(' ')} ...`;
}
return message;
}
render () {
if (this.state.error) {
return (
<CrashMessageComponent
errorMessage={this.formatErrorMessage()}
onReload={this.handleReload}
/>
);
}
return this.props.children;
}
}
ErrorBoundary.propTypes = {
action: PropTypes.string.isRequired, // Used for defining tracking action
children: PropTypes.node
};
export default ErrorBoundary;
|