Skip to content

Add dashboard-scoped error.tsx for better error recovery UX #1195

@MODSetter

Description

@MODSetter

Description

Currently the entire app has only one error.tsx boundary at the root level (surfsense_web/app/error.tsx). There are no segment-scoped error boundaries under app/dashboard/.

This means:

  • Any unhandled error inside any dashboard route shows the root-level generic error UI
  • The user loses all dashboard context (sidebar, navigation) when an error occurs
  • The reset() function tries to re-render the entire page tree instead of just the failed segment

The current root error page (for reference):

// surfsense_web/app/error.tsx
export default function ErrorPage({ error, reset }) {
    // captures to PostHog
    return (
        <div className="flex min-h-[50vh] ...">
            <h2>Something went wrong</h2>
            <button onClick={reset}>Try again</button>
        </div>
    );
}

What to do

  1. Create surfsense_web/app/dashboard/error.tsx
  2. This should be a "use client" component that:
    • Shows a dashboard-appropriate error message
    • Preserves the dashboard layout (sidebar stays visible since it's in layout.tsx)
    • Offers a reset() button to retry the failed segment
    • Optionally offers a "Go to dashboard home" link
    • Reports to PostHog (following the pattern in root error.tsx)

Example structure:

"use client";

import { useEffect } from "react";
import Link from "next/link";

export default function DashboardError({ error, reset }: {
    error: Error & { digest?: string };
    reset: () => void;
}) {
    useEffect(() => {
        import("posthog-js").then(({ default: posthog }) => {
            posthog.captureException(error);
        }).catch(() => {});
    }, [error]);

    return (
        <div className="flex flex-1 flex-col items-center justify-center gap-4 p-8">
            <h2 className="text-xl font-semibold">Something went wrong</h2>
            <p className="text-muted-foreground">An error occurred in this section.</p>
            <div className="flex gap-2">
                <button onClick={reset} className="rounded-md bg-primary px-4 py-2 text-sm ...">
                    Try again
                </button>
            </div>
        </div>
    );
}

Acceptance criteria

  • app/dashboard/error.tsx exists and is a valid error boundary
  • Dashboard sidebar/layout remains visible when an error occurs inside a dashboard route
  • reset() button re-renders only the failed dashboard segment
  • next build succeeds

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions