Enhance ErrorBoundary component with auto-retry functionality
- Added auto-retry feature to ErrorBoundary for handling errors during module federation loading. - Introduced props for configuring retry behavior: autoRetry, retryDelay, and maxRetries. - Implemented retry count management and UI feedback for ongoing retries. - Updated component lifecycle methods to manage retries and cleanup effectively. - Refactored handleRetry method to reset retry count upon manual retry.
This commit is contained in:
@@ -5,20 +5,61 @@ type Props = {
|
||||
fallback?: ReactNode
|
||||
onRetry?: () => void
|
||||
showRetry?: boolean
|
||||
autoRetry?: boolean
|
||||
retryDelay?: number
|
||||
maxRetries?: number
|
||||
}
|
||||
type State = { hasError: boolean }
|
||||
type State = { hasError: boolean; retryCount: number }
|
||||
|
||||
export class ErrorBoundary extends Component<Props, State> {
|
||||
state: State = { hasError: false }
|
||||
private retryTimeoutId?: NodeJS.Timeout
|
||||
|
||||
state: State = { hasError: false, retryCount: 0 }
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
return { hasError: true }
|
||||
}
|
||||
|
||||
componentDidCatch() {}
|
||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||
// Auto-retry logic for module federation loading issues
|
||||
const maxRetries = this.props.maxRetries || 3
|
||||
if (this.props.autoRetry !== false && this.state.retryCount < maxRetries) {
|
||||
const delay = this.props.retryDelay || 2000
|
||||
this.retryTimeoutId = setTimeout(() => {
|
||||
this.setState(prevState => ({
|
||||
hasError: false,
|
||||
retryCount: prevState.retryCount + 1
|
||||
}))
|
||||
if (this.props.onRetry) {
|
||||
this.props.onRetry()
|
||||
}
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props, prevState: State) {
|
||||
// Reset retry count if error is cleared and component successfully rendered
|
||||
if (prevState.hasError && !this.state.hasError && this.state.retryCount > 0) {
|
||||
// Give it a moment to see if it stays error-free
|
||||
setTimeout(() => {
|
||||
if (!this.state.hasError) {
|
||||
this.setState({ retryCount: 0 })
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.retryTimeoutId) {
|
||||
clearTimeout(this.retryTimeoutId)
|
||||
}
|
||||
}
|
||||
|
||||
handleRetry = () => {
|
||||
this.setState({ hasError: false })
|
||||
if (this.retryTimeoutId) {
|
||||
clearTimeout(this.retryTimeoutId)
|
||||
}
|
||||
this.setState({ hasError: false, retryCount: 0 })
|
||||
if (this.props.onRetry) {
|
||||
this.props.onRetry()
|
||||
}
|
||||
@@ -43,6 +84,11 @@ export class ErrorBoundary extends Component<Props, State> {
|
||||
<h3 className="text-sm font-medium text-red-800">Something went wrong loading this section</h3>
|
||||
<div className="mt-2 text-sm text-red-700">
|
||||
<p>An error occurred while loading this component. Please try reloading it.</p>
|
||||
{this.props.autoRetry !== false && this.state.retryCount < (this.props.maxRetries || 3) && (
|
||||
<p className="mt-1 text-xs text-red-600">
|
||||
Retrying automatically... (Attempt {this.state.retryCount + 1} of {(this.props.maxRetries || 3) + 1})
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{(this.props.showRetry !== false) && (
|
||||
<div className="mt-4">
|
||||
|
||||
Reference in New Issue
Block a user