cv/app/frontend/src/components/ErrorBoundary/ErrorBoundary.tsx
2023-06-01 20:45:17 +02:00

68 lines
1.5 KiB
TypeScript

import React from "react";
type ErrorHandler = (error: Error, info: React.ErrorInfo) => void;
type ErrorHandlingComponent<Props> = (
props: Props,
error?: Error
) => React.ReactNode;
type ErrorState = { error?: Error };
function Catch<Props extends object>(
component: ErrorHandlingComponent<Props>,
errorHandler?: ErrorHandler
): React.ComponentType<Props> {
function Inner({ error, props }: { error?: Error; props: Props }) {
return <React.Fragment>{component(props, error)}</React.Fragment>;
}
return class CatchClass extends React.Component<Props, ErrorState> {
state: ErrorState = {
error: undefined,
};
static getDerivedStateFromError(error: Error) {
return { error };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
if (errorHandler) {
errorHandler(error, info);
}
}
render() {
return <Inner error={this.state.error} props={this.props} />;
}
};
}
const divStyles: React.CSSProperties = {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
};
const ErrorBoundary = Catch(function (
props: React.PropsWithChildren,
error?: Error
) {
if (error) {
return (
<div style={divStyles}>
<h2>
There was an error on the page. Please reload the application and try
again.
</h2>
<p />
<p>{error.message}</p>
</div>
);
}
return <>{props.children}</>;
});
export default ErrorBoundary;