Files
oranguru/src/ErrorBoundary/BasicErrorBoundary.tsx

79 lines
1.7 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { type PropsWithChildren } from 'react';
import errorManager from './ErrorManager';
interface ErrorBoundaryProps extends PropsWithChildren {
namespace?: string;
onReportClick?: () => void;
onResetClick?: () => void;
onRetryClick?: () => void;
reportAPI?: string;
}
interface ErrorBoundaryState {
error: any;
errorInfo: any;
reported?: boolean;
resetted?: boolean;
showDetail: boolean;
timer?: NodeJS.Timeout | undefined;
try: boolean;
tryCnt: number;
}
export class ReactBasicErrorBoundary extends React.PureComponent<
ErrorBoundaryProps,
ErrorBoundaryState
> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = {
error: null,
errorInfo: null,
showDetail: false,
timer: undefined,
try: false,
tryCnt: 0,
};
}
componentDidCatch(error: any, errorInfo: any) {
// Catch errors in any components below and re-render with error message
this.setState({
error,
errorInfo,
try: false,
});
// Report error to error manager (Sentry, custom API, etc.)
errorManager.reportError(error, errorInfo, {
componentStack: errorInfo?.componentStack,
namespace: this.props.namespace,
});
}
render() {
if (this.state.errorInfo) {
// Error path
return (
<div>
<h2>Error</h2>
{this.state.error && (
<>
<h3>In: {this.props.namespace ?? 'default'}</h3>
<main>{this.state.error.toString()}</main>
</>
)}
</div>
);
}
// Normally, just render children
return this.props.children;
}
}
export default ReactBasicErrorBoundary;