Skip to content

Replace ErrorBoundary with Expo Router-compatible error boundary #18

@bobbyg603

Description

@bobbyg603

Problem

The current ErrorBoundary (re-exported from @bugsplat/react) doesn't integrate with Expo Router's navigation lifecycle. When users wrap <Slot /> with <ErrorBoundary>, Expo Router detects the failed render independently and reverts the URL before the fallback is shown — causing a redirect to the previous page.

This happens because Expo Router only recognizes error boundaries that are exported from route/layout files using its ErrorBoundaryProps API ({ error, retry }). Its internal Try component wraps routes that export an ErrorBoundary, which integrates with the navigation state so the URL stays at the destination page.

The @bugsplat/react ErrorBoundary is a general-purpose React error boundary — it works great in plain React but fights Expo Router's navigation system.

Current workaround

Users have to manually wire up an Expo Router-compatible error boundary in each layout file:

// app/(app)/_layout.tsx
import { type ErrorBoundaryProps } from "expo-router";
import { post } from "@bugsplat/expo";

export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
  // manually call post(), build fallback UI, etc.
}

This is boilerplate that every @bugsplat/expo user with Expo Router will need to write.

Proposal

Replace the re-exported ErrorBoundary from @bugsplat/react with an Expo Router-native error boundary that:

  1. Accepts Expo Router's { error, retry } props so it can be directly exported from layout/route files
  2. Automatically calls post() with the error (respecting disablePost)
  3. Provides a default fallback UI (or accepts a custom fallback render prop)
  4. Includes route context (usePathname()) in the error report attributes

Example API:

// app/(app)/_layout.tsx
import { ErrorBoundary } from "@bugsplat/expo";
export { ErrorBoundary };

// or with customization:
import { createErrorBoundary } from "@bugsplat/expo";
export const ErrorBoundary = createErrorBoundary({
  disablePost: false,
  fallback: ({ error, retry, post }) => <MyCustomFallback ... />,
});

This would also be a good opportunity to deprecate the re-exports of ErrorBoundary, useErrorHandler, withErrorBoundary, FallbackProps, FallbackElement, and FallbackRender from @bugsplat/react, since they don't work correctly in an Expo Router context.

Context

Discovered while adding error boundaries to an Expo Router app. The @bugsplat/react ErrorBoundary caught errors but Expo Router reverted the URL, causing the route attribute in crash reports to show the wrong page. Switching to Expo Router's ErrorBoundary export API fixed both the redirect and the route tracking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions