Operations

Automatic error reports

How RemixCRM catches uncaught errors and files them in your support inbox.

What it does

When something throws an uncaught exception in RemixCRM — a server action, a React tree, anything — the user sees a friendly recovery page instead of a generic "page couldn't load" screen, and the error is automatically filed in your bug-reports inbox with the stack trace, page URL, browser info, and a unique digest ID.

You don't have to ask users to report bugs. They're already reported.

What the user sees

A dark recovery page with:

  • "Something went wrong"
  • A reassuring message ("We've been notified")
  • The error ID (a digest like 3457432882) and the report ID (a1b2c3d4)
  • Try again button (re-renders the failed segment)
  • Go home link

If your user emails you the error ID, you can grep Railway logs for it to find the underlying stack trace.

Where reports show up

In Supabase (or your existing support dashboard), the bug_reports table:

select id, description, page_url, created_at
  from bug_reports
 where category = 'auto'
 order by created_at desc
 limit 20;

Auto-reports are tagged category = 'auto' to distinguish them from user-initiated reports filed via the support chat.

Deduplication

The same error digest from the same page is recorded once per 15 minutes. This prevents a viral bug (e.g. a popular page broken for all users) from generating thousands of duplicate rows. After 15 minutes, a new row is filed so you can tell the difference between "bug we fixed" and "bug came back."

How it works under the hood

  1. React tree throws
  2. Next.js renders app/global-error.tsx (root) or app/(app)/error.tsx (app routes)
  3. That component fires a useEffect that POSTs to /api/auto-error-report with the digest, message, stack, page URL, and browser info
  4. The endpoint inserts a bug_reports row with category = 'auto'
  5. The dedupe check skips inserts if the same digest + URL was already reported in the last 15 minutes

The POST uses keepalive: true so it survives the user clicking "Go home" mid-fetch.

What's captured

Field Source
digest Next.js error digest (hash of the error message)
message First 2000 chars
stack First 8000 chars
page_url window.location.href
browser_info User agent, language, viewport

What's NOT captured

  • User identity (the report is anonymous — org_id and user_id are null). This is intentional: the endpoint runs without authentication so it can also catch errors on the login page or other public routes.
  • Form data
  • Cookies, localStorage, or any session state

If you want richer attribution (which user, which org), wire Sentry — see Operations roadmap.

Tuning

To find auto-report code:

  • app/global-error.tsx — UI + the POST
  • app/api/auto-error-report/route.ts — server-side insert + dedupe

Both are short and easy to extend if you want to capture additional context or change the recovery UI.