Duffer Derek

Current Path : /var/www/sitesecurity.bitkit.dk/httpdocs/src/components/
Upload File :
Current File : /var/www/sitesecurity.bitkit.dk/httpdocs/src/components/ErrorBoundary.tsx

"use client";

import React, { Component, ErrorInfo, ReactNode } from "react";
import { IOSErrorFallback } from "./IOSErrorFallback";
import { isIOSDevice } from "@/lib/iosPWAUtils";

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
}

interface State {
  hasError: boolean;
  error?: Error;
  errorInfo?: ErrorInfo;
}

class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error): State {
    // Update state so the next render will show the fallback UI
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Log error details
    console.error("ErrorBoundary caught an error:", error, errorInfo);

    // Store error info in state
    this.setState({
      error,
      errorInfo,
    });

    // Log to external service if needed
    this.logErrorToService(error, errorInfo);
  }

  private logErrorToService = (error: Error, errorInfo: ErrorInfo) => {
    // Enhanced error logging for iOS PWA issues
    const errorDetails = {
      message: error.message,
      stack: error.stack,
      componentStack: errorInfo.componentStack,
      userAgent: navigator.userAgent,
      isIOS: /iPhone|iPad|iPod/.test(navigator.userAgent),
      isPWA:
        window.matchMedia("(display-mode: standalone)").matches ||
        (window.navigator as any).standalone === true,
      timestamp: new Date().toISOString(),
      url: window.location.href,
    };

    console.error("Detailed error information:", errorDetails);

    // Special handling for Notification API errors
    if (error.message.includes("Can't find variable: Notification")) {
      console.warn(
        "Notification API error detected - this is expected on some iOS Safari versions"
      );
      // Reset error state for this specific case
      this.setState({ hasError: false, error: undefined, errorInfo: undefined });
      return;
    }

    // You can send this to your error tracking service
    // Example: Sentry, LogRocket, etc.
  };

  private handleRetry = () => {
    this.setState({ hasError: false, error: undefined, errorInfo: undefined });
  };

  private handleReload = () => {
    window.location.reload();
  };

  render() {
    if (this.state.hasError) {
      // Custom fallback UI
      if (this.props.fallback) {
        return this.props.fallback;
      }

      // iOS-specific error UI
      if (isIOSDevice()) {
        return (
          <IOSErrorFallback
            error={this.state.error}
            onRetry={this.handleRetry}
            onReload={this.handleReload}
          />
        );
      }

      // Default error UI
      return (
        <div
          style={{
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            minHeight: "100vh",
            padding: "20px",
            textAlign: "center",
            backgroundColor: "#f5f5f5",
            fontFamily: "system-ui, -apple-system, sans-serif",
          }}
        >
          <div
            style={{
              backgroundColor: "white",
              padding: "30px",
              borderRadius: "8px",
              boxShadow: "0 2px 10px rgba(0,0,0,0.1)",
              maxWidth: "500px",
              width: "100%",
            }}
          >
            <h1 style={{ color: "#e30613", marginBottom: "20px" }}>Something went wrong</h1>

            <p style={{ marginBottom: "20px", color: "#666" }}>
              We're sorry, but something unexpected happened. This might be a temporary issue.
            </p>

            {/* Show error details in development */}
            {process.env.NODE_ENV === "development" && this.state.error && (
              <details
                style={{
                  marginBottom: "20px",
                  textAlign: "left",
                  backgroundColor: "#f8f8f8",
                  padding: "15px",
                  borderRadius: "4px",
                  border: "1px solid #ddd",
                }}
              >
                <summary style={{ cursor: "pointer", fontWeight: "bold" }}>
                  Error Details (Development)
                </summary>
                <pre
                  style={{
                    fontSize: "12px",
                    overflow: "auto",
                    marginTop: "10px",
                    whiteSpace: "pre-wrap",
                  }}
                >
                  {this.state.error.message}
                  {this.state.error.stack && `\n\nStack:\n${this.state.error.stack}`}
                </pre>
              </details>
            )}

            <div style={{ display: "flex", gap: "10px", justifyContent: "center" }}>
              <button
                onClick={this.handleRetry}
                style={{
                  backgroundColor: "#e30613",
                  color: "white",
                  border: "none",
                  padding: "10px 20px",
                  borderRadius: "4px",
                  cursor: "pointer",
                  fontSize: "14px",
                }}
              >
                Try Again
              </button>

              <button
                onClick={this.handleReload}
                style={{
                  backgroundColor: "#666",
                  color: "white",
                  border: "none",
                  padding: "10px 20px",
                  borderRadius: "4px",
                  cursor: "pointer",
                  fontSize: "14px",
                }}
              >
                Reload Page
              </button>
            </div>

            {/* iOS-specific help */}
            {/iPhone|iPad|iPod/.test(navigator.userAgent) && (
              <div
                style={{
                  marginTop: "20px",
                  padding: "15px",
                  backgroundColor: "#fff3cd",
                  border: "1px solid #ffeaa7",
                  borderRadius: "4px",
                  fontSize: "14px",
                }}
              >
                <strong>iOS Users:</strong> If this error persists, try:
                <ul style={{ textAlign: "left", marginTop: "10px" }}>
                  <li>Close and reopen the app</li>
                  <li>Clear Safari cache in Settings</li>
                  <li>Update to the latest iOS version</li>
                </ul>
              </div>
            )}
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists