2022-01-11 07:50:41 +01:00
|
|
|
import React, { ErrorInfo } from "react";
|
2022-01-10 17:29:58 +01:00
|
|
|
|
|
|
|
import { IErrorData, getErrorForDisplay } from "../utils/ErrorHelper";
|
2022-01-11 07:50:41 +01:00
|
|
|
import { RecoveryRoot } from "./React/RecoveryRoot";
|
2022-01-10 17:29:58 +01:00
|
|
|
import { IRouter, Page } from "./Router";
|
2022-01-11 07:50:41 +01:00
|
|
|
|
|
|
|
interface IProps {
|
|
|
|
router: IRouter;
|
|
|
|
softReset: () => void;
|
|
|
|
}
|
|
|
|
|
2022-01-10 17:29:58 +01:00
|
|
|
interface IState {
|
|
|
|
error?: Error;
|
|
|
|
errorInfo?: React.ErrorInfo;
|
|
|
|
page?: Page;
|
|
|
|
hasError: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ErrorBoundary extends React.Component<IProps, IState> {
|
|
|
|
state: IState
|
2022-01-11 07:50:41 +01:00
|
|
|
|
|
|
|
constructor(props: IProps) {
|
|
|
|
super(props);
|
2022-01-10 17:29:58 +01:00
|
|
|
this.state = { hasError: false } as IState;
|
|
|
|
}
|
|
|
|
|
|
|
|
reset(): void {
|
|
|
|
this.setState( { hasError: false } as IState);
|
2022-01-11 07:50:41 +01:00
|
|
|
}
|
2022-01-10 17:29:58 +01:00
|
|
|
|
2022-01-11 07:50:41 +01:00
|
|
|
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
|
2022-01-10 17:29:58 +01:00
|
|
|
this.setState({
|
|
|
|
errorInfo,
|
|
|
|
page: this.props.router.page(),
|
|
|
|
});
|
2022-01-11 07:50:41 +01:00
|
|
|
console.error(error, errorInfo);
|
|
|
|
}
|
|
|
|
render(): React.ReactNode {
|
|
|
|
if (this.state.hasError) {
|
2022-01-10 17:29:58 +01:00
|
|
|
let errorData: IErrorData | undefined;
|
|
|
|
if (this.state.error) {
|
|
|
|
try {
|
|
|
|
// We don't want recursive errors, so in case this fails, it's in a try catch.
|
|
|
|
errorData = getErrorForDisplay(this.state.error, this.state.errorInfo, this.state.page);
|
|
|
|
} catch (ex) {
|
|
|
|
console.error(ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return <RecoveryRoot router={this.props.router} softReset={this.props.softReset}
|
|
|
|
errorData={errorData} resetError={() => this.reset()} />;
|
2022-01-11 07:50:41 +01:00
|
|
|
}
|
|
|
|
return this.props.children;
|
|
|
|
}
|
2022-01-10 17:29:58 +01:00
|
|
|
static getDerivedStateFromError(error: Error): IState {
|
|
|
|
return { hasError: true, error};
|
2022-01-11 07:50:41 +01:00
|
|
|
}
|
2022-01-10 17:29:58 +01:00
|
|
|
}
|