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:
salirezav
2026-01-14 16:41:03 -05:00
parent afefd32c3b
commit c54385a90c
3 changed files with 108 additions and 5 deletions

View File

@@ -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">