Skip to content

Comments

feat: add error.tsx component#49

Open
afuhflynn wants to merge 3 commits intoAnmolSaini16:mainfrom
afuhflynn:feature/error-fallback-page
Open

feat: add error.tsx component#49
afuhflynn wants to merge 3 commits intoAnmolSaini16:mainfrom
afuhflynn:feature/error-fallback-page

Conversation

@afuhflynn
Copy link

@afuhflynn afuhflynn commented Feb 19, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a user-friendly error page that displays when application errors occur, with options to retry the action or return to the home page.
  • Chores

    • Updated workspace configuration for dependency management optimization.

@vercel
Copy link

vercel bot commented Feb 19, 2026

@afuhflynn is attempting to deploy a commit to the anmolsaini16's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

Two changes are introduced: a configuration update to pnpm-workspace.yaml specifying built dependencies (msw, sharp, unrs-resolver) for dependency hoisting, and a new client-side error page component in src/app/error.tsx that displays user-friendly error messages with recovery and navigation actions.

Changes

Cohort / File(s) Summary
Workspace Configuration
pnpm-workspace.yaml
Adds onlyBuiltDependencies mapping listing msw, sharp, and unrs-resolver as built dependencies to control workspace dependency hoisting behavior.
Error Handling
src/app/error.tsx
New client-side error page component with ErrorPage function that logs errors, displays an alert UI with headline and message, and provides "Try again" button (calls reset) and "Back to Home" navigation link.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A config tweak and error page so neat,
Built deps now arranged, the workspace feels complete,
When errors arise with a friendly face,
Users can recover or return to their place! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add error.tsx component' directly corresponds to the main change in the PR, which adds a new error handling component file.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/app/errror.tsx (2)

9-9: Component name Error shadows the global built-in Error class.

While TypeScript resolves the prop type annotation at the type level, naming the component Error shadows the global Error constructor inside the module. Any future maintainer who needs to construct a new Error object inside this component body will get a runtime failure. Consider renaming to ErrorPage or ErrorFallback.

♻️ Proposed fix
-export default function Error({
+export default function ErrorPage({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/errror.tsx` at line 9, The component function named Error shadows the
global Error constructor; rename the function and default export to a
non-conflicting identifier (e.g., ErrorPage or ErrorFallback) by changing the
function declaration "export default function Error(...)" to "export default
function ErrorPage(...)" (or chosen name), keep the same props/type signature,
and update any imports/usages across the codebase to the new name so the module
no longer hides the global Error symbol.

12-14: Extract inline prop type to a named interface.

Per coding guidelines, prefer interfaces over inline type literals for component props.

♻️ Proposed refactor
+interface ErrorProps {
+  error: Error & { digest?: string };
+  reset: () => void;
+}
+
-export default function Error({
+export default function ErrorPage({
   error,
   reset,
-}: {
-  error: Error & { digest?: string };
-  reset: () => void;
-}) {
+}: ErrorProps) {

As per coding guidelines: "Use TypeScript for all code; prefer interfaces over types."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/errror.tsx` around lines 12 - 14, Extract the inline prop type into a
named interface (e.g., ErrorProps) and use it in the component signature:
declare an interface with fields error: Error & { digest?: string } and reset:
() => void, then replace the inline annotation (the current ": { error: Error &
{ digest?: string }; reset: () => void; }") with the new interface name where
the component is declared so the component consumes ErrorProps instead of an
anonymous inline type.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/errror.tsx`:
- Line 7: The import/use of useRouter and the router.refresh() fallback are dead
because reset is declared non-optional and always truthy; remove the unnecessary
useRouter import and any router.refresh() branch (i.e., delete the useRouter()
call and the ternary/fallback that calls router.refresh()), and either leave the
component to call reset() directly or if you need the fallback behavior instead,
change the prop signature of reset to optional (reset?: () => void) and guard
its call; reference the useRouter symbol, router.refresh(), and the reset prop
to locate and update the code.
- Around line 38-41: The "Try again" button has duplicated spacing because the
wrapper span with className "gap-2" and the RefreshCw icon both add right
margin; remove the redundant margin by deleting the "mr-2" class from the
RefreshCw component (or alternatively remove "gap-2" from the span) so spacing
is controlled only once; update the JSX around the span and RefreshCw in
src/app/errror.tsx accordingly.
- Line 1: The file is incorrectly named "errror.tsx" (three r's) so Next.js
won't register it as the app error boundary; rename the file from errror.tsx to
error.tsx and ensure any imports or references (if present) point to the new
filename so the error boundary component is recognized and used by the Next.js
router.

---

Nitpick comments:
In `@src/app/errror.tsx`:
- Line 9: The component function named Error shadows the global Error
constructor; rename the function and default export to a non-conflicting
identifier (e.g., ErrorPage or ErrorFallback) by changing the function
declaration "export default function Error(...)" to "export default function
ErrorPage(...)" (or chosen name), keep the same props/type signature, and update
any imports/usages across the codebase to the new name so the module no longer
hides the global Error symbol.
- Around line 12-14: Extract the inline prop type into a named interface (e.g.,
ErrorProps) and use it in the component signature: declare an interface with
fields error: Error & { digest?: string } and reset: () => void, then replace
the inline annotation (the current ": { error: Error & { digest?: string };
reset: () => void; }") with the new interface name where the component is
declared so the component consumes ErrorProps instead of an anonymous inline
type.

@@ -0,0 +1,52 @@
"use client";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: filename typo makes this error boundary completely non-functional.

The file is saved as errror.tsx (three rs). When an uncaught error occurs in a component, the router will render the error component defined as error.tsx — if it exists. Because the filename doesn't match the exact convention, Next.js will never register this file as an error boundary, and all unhandled runtime errors in the app will fall through to the default (bare) error page instead.

Rename the file:

src/app/errror.tsx → src/app/error.tsx
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/errror.tsx` at line 1, The file is incorrectly named "errror.tsx"
(three r's) so Next.js won't register it as the app error boundary; rename the
file from errror.tsx to error.tsx and ensure any imports or references (if
present) point to the new filename so the error boundary component is recognized
and used by the Next.js router.

import Link from "next/link";
import { Button } from "@/components/ui/button";
import { AlertCircle, ArrowLeft, RefreshCw } from "lucide-react";
import { useRouter } from "next/navigation";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Dead router.refresh() branch makes useRouter an unnecessary import.

reset is typed as a required, non-optional prop (reset: () => void). A non-nullable function reference is always truthy, so the ternary on Line 34 will always call reset() and the router.refresh() fallback is unreachable dead code. Consequently, useRouter (Line 7) is imported and instantiated for no effect.

🛠 Proposed fix
-import { useRouter } from "next/navigation";
 
 export default function Error({
   error,
   reset,
 }: {
   error: Error & { digest?: string };
   reset: () => void;
 }) {
-  const router = useRouter();
   useEffect(() => {
     console.error(error);
   }, [error]);
 
   ...
         <Button
-          onClick={() => (reset ? reset() : router.refresh())}
+          onClick={reset}
           variant="outline"

Also applies to: 34-34

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/errror.tsx` at line 7, The import/use of useRouter and the
router.refresh() fallback are dead because reset is declared non-optional and
always truthy; remove the unnecessary useRouter import and any router.refresh()
branch (i.e., delete the useRouter() call and the ternary/fallback that calls
router.refresh()), and either leave the component to call reset() directly or if
you need the fallback behavior instead, change the prop signature of reset to
optional (reset?: () => void) and guard its call; reference the useRouter
symbol, router.refresh(), and the reset prop to locate and update the code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/app/error.tsx (2)

28-40: Inconsistent icon-spacing patterns between the two buttons.

The "Try again" button wraps its content in a <span> with gap-2, while "Back to Home" applies mr-2 directly on the icon with no wrapper. Pick one approach for consistency. Since the <Link> already has flex classes, you could drop the extra <span> and apply the same flex layout via the Button's className:

♻️ Suggested unification
         <Button onClick={reset} variant="outline" className="w-full md:w-auto">
-          <span className="flex flex-row items-center gap-2">
-            <RefreshCw className="h-4 w-4" />
-            Try again
-          </span>
+          <RefreshCw className="mr-2 h-4 w-4" />
+          Try again
         </Button>
         <Button asChild className="w-full md:w-auto font-sans">
           <Link href="/" className="flex flex-row items-center justify-center">
             <ArrowLeft className="mr-2 h-4 w-4" />
             Back to Home
           </Link>
         </Button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/error.tsx` around lines 28 - 40, The two buttons in the Error
component use inconsistent icon spacing: the "Try again" Button wraps content in
a span with gap-2 and icon RefreshCw, while the "Back to Home" Button applies
mr-2 to ArrowLeft directly; make them consistent by using the same flex/gap
pattern for both Buttons (remove the extra span or add one to the Link) so both
use a flex container with gap-2; update the Button rendering around reset/Link
and the elements RefreshCw and ArrowLeft to match the chosen pattern.

13-16: Consider integrating a real error reporting service.

The comment mentions logging to an error reporting service, but the implementation only uses console.error. This is fine for development, but in production, errors here will be silently lost. Consider wiring this up to Sentry, LogRocket, or a similar service when ready.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/error.tsx` around lines 13 - 16, The useEffect in the error boundary
currently calls console.error(error) which only aids development; replace this
with a call to your chosen error reporting client (e.g.,
Sentry.captureException, LogRocket.captureException, or a wrapper like
reportError) inside the same useEffect so runtime errors are sent to a service;
update the import and initialization where appropriate and ensure
useEffect([error]) calls the reporting function with the error and any
contextual metadata before or instead of console.error to preserve current
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/app/error.tsx`:
- Around line 28-40: The two buttons in the Error component use inconsistent
icon spacing: the "Try again" Button wraps content in a span with gap-2 and icon
RefreshCw, while the "Back to Home" Button applies mr-2 to ArrowLeft directly;
make them consistent by using the same flex/gap pattern for both Buttons (remove
the extra span or add one to the Link) so both use a flex container with gap-2;
update the Button rendering around reset/Link and the elements RefreshCw and
ArrowLeft to match the chosen pattern.
- Around line 13-16: The useEffect in the error boundary currently calls
console.error(error) which only aids development; replace this with a call to
your chosen error reporting client (e.g., Sentry.captureException,
LogRocket.captureException, or a wrapper like reportError) inside the same
useEffect so runtime errors are sent to a service; update the import and
initialization where appropriate and ensure useEffect([error]) calls the
reporting function with the error and any contextual metadata before or instead
of console.error to preserve current behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant