11'use client'
22
3- import { Component , type ReactNode , useEffect } from 'react'
3+ import { Component , type ErrorInfo , type ReactNode , useEffect } from 'react'
44import { Button } from '@sim/emcn'
55import { RefreshCw } from '@sim/emcn/icons'
66import { createLogger } from '@sim/logger'
@@ -12,6 +12,36 @@ import { readCollapsedCookie } from '@/stores/sidebar/store'
1212
1313const logger = createLogger ( 'ErrorBoundary' )
1414
15+ /**
16+ * Reports a boundary error to PostHog.
17+ *
18+ * Nothing else in the app ships client exceptions anywhere, so a crash on this
19+ * route survives only in the console of whoever hit it — which is why the same
20+ * "Something went wrong" report has had to be diagnosed from screenshots. The
21+ * env snapshot travels with the event because the failures seen so far read an
22+ * empty `NEXT_PUBLIC_APP_URL`, and whether `window.__ENV` was populated at all
23+ * separates a missing deployment value from a document that never ran the
24+ * assignment.
25+ *
26+ * `posthog-js` is imported lazily so the editor route keeps the code-splitting
27+ * the provider sets up, and only pays for the import on the error path.
28+ */
29+ function reportBoundaryError ( error : Error , context : Record < string , unknown > ) : void {
30+ if ( typeof window === 'undefined' ) return
31+
32+ void import ( 'posthog-js' )
33+ . then ( ( { default : posthog } ) => {
34+ if ( ! posthog . __loaded ) return
35+ posthog . captureException ( error , {
36+ ...context ,
37+ pathname : window . location . pathname ,
38+ public_env_present : window . __ENV !== undefined ,
39+ app_url_present : Boolean ( window . __ENV ?. NEXT_PUBLIC_APP_URL ) ,
40+ } )
41+ } )
42+ . catch ( ( ) => { } )
43+ }
44+
1545/**
1646 * Shared Error UI Component
1747 */
@@ -90,6 +120,11 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
90120 return { hasError : true , error }
91121 }
92122
123+ public componentDidCatch ( error : Error , info : ErrorInfo ) : void {
124+ logger . error ( 'Workflow boundary error:' , { error, componentStack : info . componentStack } )
125+ reportBoundaryError ( error , { component_stack : info . componentStack } )
126+ }
127+
93128 public render ( ) {
94129 if ( this . state . hasError ) {
95130 return this . props . fallback || < ErrorUI />
@@ -111,6 +146,7 @@ interface NextErrorProps {
111146export function NextError ( { error, reset } : NextErrorProps ) {
112147 useEffect ( ( ) => {
113148 logger . error ( 'Workflow error:' , { error } )
149+ reportBoundaryError ( error , { digest : error . digest } )
114150 } , [ error ] )
115151
116152 return < ErrorUI onReset = { reset } />
0 commit comments