Files
bodyshop/client/src/components/error-boundary/error-boundary.component.jsx

144 lines
4.2 KiB
JavaScript

import * as Sentry from "@sentry/react";
import { Button, Col, Collapse, Result, Row, Space } from "antd";
import React from "react";
import { withTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
class ErrorBoundary extends React.Component {
constructor() {
super();
this.state = {
hasErrored: false,
error: null,
info: null
};
}
static getDerivedStateFromError(error) {
console.log("ErrorBoundary -> getDerivedStateFromError -> error", error);
return { hasErrored: true, error: error };
}
componentDidCatch(error, info) {
console.log("Exception Caught by Error Boundary.", error, info);
this.setState({ ...this.state, error, info });
}
handleErrorSubmit = () => {
window.$crisp.push([
"do",
"message:send",
[
"text",
`I hit the following error: \n\n
${this.state.error.message}\n\n
${this.state.error.stack}\n\n
URL:${window.location} as ${this.props.currentUser.email} for ${
this.props.bodyshop && this.props.bodyshop.name
}
`
]
]);
window.$crisp.push(["do", "chat:open"]);
// const errorDescription = `**Please add relevant details about what you were doing before you encountered this issue**
// ----
// System Generated Log:
// ${this.state.error.message}
// ${this.state.error.stack}
// `;
// const URL = `https://bodyshop.atlassian.net/servicedesk/customer/portal/3/group/8/create/26?summary=123&description=${encodeURI(
// errorDescription
// )}&customfield_10049=${window.location}&email=${
// this.props.currentUser.email
// }`;
// console.log(`URL`, URL);
// window.open(URL, "_blank");
};
render() {
const { t } = this.props;
const { error, info } = this.state;
if (this.state.hasErrored === true) {
logImEXEvent("error_boundary_rendered", { error, info });
window.$crisp.push([
"set",
"session:event",
[
[
[
"error_boundary",
{
error: this.state.error.message,
stack: this.state.error.stack
},
"red"
]
]
]
]);
return (
<div>
<Result
status="500"
title={t("general.labels.exceptiontitle")}
subTitle={t("general.messages.exception", {
app: InstanceRenderManager({
imex: "$t(titles.imexonline)",
rome: "$t(titles.romeonline)"
})
})}
extra={
<Space>
<Button
type="primary"
onClick={() => {
window.location.reload();
}}
>
{t("general.actions.refresh")}
</Button>
<Button onClick={this.handleErrorSubmit}>{t("general.actions.senderrortosupport")}</Button>
</Space>
}
/>
<Row>
<Col offset={6} span={12}>
<Collapse bordered={false}>
<Collapse.Panel key="errors-panel" header={t("general.labels.errors")}>
<div>
<strong>{this.state.error.message}</strong>
</div>
<div>{this.state.error.stack}</div>
</Collapse.Panel>
</Collapse>
</Col>
</Row>
</div>
);
} else {
return this.props.children;
}
}
}
export default Sentry.withErrorBoundary(connect(mapStateToProps, mapDispatchToProps)(withTranslation()(ErrorBoundary)));