Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 1x 1x 1x 1x 1x 29x 30x 30x 30x 29x 16x 16x 29x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 29x 1x 1x 29x 65x 24x 3x 3x 21x 21x 21x 21x 21x 24x 24x 24x 24x 24x 24x 24x 3x 3x 3x 3x 3x 3x 3x 3x 24x 24x 24x 24x 24x 24x 24x 24x 24x 41x 65x 29x 1x 2x 2x 2x 2x 4x 4x 4x 2x | 'use client';
import { Button } from '@web/components/ui/button';
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from '@web/components/ui/card';
import { AlertCircle, RefreshCw } from 'lucide-react';
import React, { Component, type ErrorInfo, type ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: (error: Error, resetError: () => void) => ReactNode;
sectionName?: string;
}
interface State {
hasError: boolean;
error: Error | null;
errorInfo: ErrorInfo | null;
}
export class AgentErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false, error: null, errorInfo: null };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error, errorInfo: null };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
// Log error to monitoring service
console.error('Agent section error:', {
section: this.props.sectionName,
error: error.toString(),
stack: errorInfo.componentStack,
timestamp: new Date().toISOString(),
});
// Track error metrics
if (window?.performance) {
performance.mark(`agent-error-${this.props.sectionName || 'unknown'}`);
}
this.setState({ errorInfo });
}
resetError = () => {
this.setState({ hasError: false, error: null, errorInfo: null });
};
render() {
if (this.state.hasError) {
// Use custom fallback if provided
if (this.props.fallback) {
return this.props.fallback(this.state.error!, this.resetError);
}
// Default error UI
return (
<Card className="border-destructive">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-destructive">
<AlertCircle className="h-5 w-5" />
Error in {this.props.sectionName || 'Agent Section'}
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-sm text-muted-foreground">
Something went wrong while loading this section. The error has
been logged.
</p>
{process.env.NODE_ENV === 'development' && this.state.error && (
<details className="text-xs">
<summary className="cursor-pointer text-muted-foreground hover:text-foreground">
Error Details (Development Only)
</summary>
<pre className="mt-2 p-2 bg-muted rounded overflow-auto">
{this.state.error.toString()}
{this.state.errorInfo?.componentStack}
</pre>
</details>
)}
<Button
onClick={this.resetError}
variant="outline"
className="gap-2"
>
<RefreshCw className="h-4 w-4" />
Try Again
</Button>
</CardContent>
</Card>
);
}
return this.props.children;
}
}
// HOC for wrapping agent components with error boundary
export function withAgentErrorBoundary<P extends object>(
Component: React.ComponentType<P>,
sectionName: string,
) {
return (props: P) => (
<AgentErrorBoundary sectionName={sectionName}>
<Component {...props} />
</AgentErrorBoundary>
);
}
|