spb/vquant Public MIT
VibeQuant — AI-powered institutional-grade financial intelligence platform.
TypeScript 84.3%
Python 11.7%
JavaScript 1.6%
CSS 1.5%
HTML 0.7%
1/*2 * =============================================================================3 * VibeQuant (vquant) — AI-Powered Financial Intelligence Platform4 * -----------------------------------------------------------------------------5 * File: client/src/components/error-boundary.tsx6 *7 * Author: Simon-Pierre Boucher8 * Contact: contact@spboucher.ai9 * Website: https://www.spboucher.ai10 * Demo: https://www.vquant.ai11 * License: MIT (see LICENSE)12 *13 * Copyright © 2026 Simon-Pierre Boucher. All rights reserved.14 * =============================================================================15 */1617import { Component, type ErrorInfo, type ReactNode } from "react";18import { Button } from "@/components/ui/button";19import { AlertTriangle } from "lucide-react";2021interface Props {22 children: ReactNode;23 fallback?: ReactNode;24}2526interface State {27 hasError: boolean;28 error: Error | null;29}3031export class ErrorBoundary extends Component<Props, State> {32 constructor(props: Props) {33 super(props);34 this.state = { hasError: false, error: null };35 }3637 static getDerivedStateFromError(error: Error): State {38 return { hasError: true, error };39 }4041 componentDidCatch(error: Error, info: ErrorInfo) {42 console.error("ErrorBoundary caught:", error, info.componentStack);43 }4445 handleReset = () => {46 this.setState({ hasError: false, error: null });47 };4849 render() {50 if (this.state.hasError) {51 if (this.props.fallback) {52 return this.props.fallback;53 }5455 return (56 <div className="flex flex-col items-center justify-center min-h-[50vh] gap-6 p-8">57 <div className="flex items-center gap-3 text-destructive">58 <AlertTriangle className="h-8 w-8" />59 <h2 className="text-xl font-semibold">Something went wrong</h2>60 </div>61 <p className="text-muted-foreground text-center max-w-md">62 An unexpected error occurred. You can try refreshing the page or click the button below.63 </p>64 {this.state.error && (65 <pre className="text-xs text-muted-foreground bg-muted p-4 rounded-lg max-w-lg overflow-auto">66 {this.state.error.message}67 </pre>68 )}69 <div className="flex gap-3">70 <Button variant="outline" onClick={this.handleReset}>71 Try again72 </Button>73 <Button onClick={() => window.location.reload()}>74 Reload page75 </Button>76 </div>77 </div>78 );79 }8081 return this.props.children;82 }83}84