@error-explorer/react 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +39 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +39 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -163,22 +163,37 @@ var ErrorBoundary = class extends import_react2.Component {
|
|
|
163
163
|
}
|
|
164
164
|
componentDidCatch(error, errorInfo) {
|
|
165
165
|
this.setState({ errorInfo });
|
|
166
|
-
const {
|
|
166
|
+
const {
|
|
167
|
+
capture = true,
|
|
168
|
+
captureComponentStack = true,
|
|
169
|
+
beforeReactCapture,
|
|
170
|
+
tags = {},
|
|
171
|
+
context = {},
|
|
172
|
+
onError
|
|
173
|
+
} = this.props;
|
|
167
174
|
if (onError) {
|
|
168
175
|
onError(error, errorInfo);
|
|
169
176
|
}
|
|
170
|
-
if (capture) {
|
|
171
|
-
|
|
172
|
-
tags: {
|
|
173
|
-
"react.errorBoundary": "true",
|
|
174
|
-
...tags
|
|
175
|
-
},
|
|
176
|
-
extra: {
|
|
177
|
-
componentStack: errorInfo.componentStack,
|
|
178
|
-
...context
|
|
179
|
-
}
|
|
180
|
-
});
|
|
177
|
+
if (!capture) {
|
|
178
|
+
return;
|
|
181
179
|
}
|
|
180
|
+
if (beforeReactCapture) {
|
|
181
|
+
const shouldCapture = beforeReactCapture(error, errorInfo);
|
|
182
|
+
if (shouldCapture === false) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const extra = { ...context };
|
|
187
|
+
if (captureComponentStack && errorInfo.componentStack) {
|
|
188
|
+
extra.componentStack = errorInfo.componentStack;
|
|
189
|
+
}
|
|
190
|
+
import_browser2.ErrorExplorer.captureException(error, {
|
|
191
|
+
tags: {
|
|
192
|
+
"react.errorBoundary": "true",
|
|
193
|
+
...tags
|
|
194
|
+
},
|
|
195
|
+
extra
|
|
196
|
+
});
|
|
182
197
|
}
|
|
183
198
|
componentDidUpdate(prevProps) {
|
|
184
199
|
const { resetKeys } = this.props;
|
|
@@ -214,17 +229,28 @@ var ErrorBoundary = class extends import_react2.Component {
|
|
|
214
229
|
};
|
|
215
230
|
ErrorBoundary.defaultProps = {
|
|
216
231
|
capture: true,
|
|
232
|
+
captureComponentStack: true,
|
|
217
233
|
tags: {},
|
|
218
234
|
context: {}
|
|
219
235
|
};
|
|
220
236
|
function withErrorBoundary(Component2, options = {}) {
|
|
221
|
-
const {
|
|
237
|
+
const {
|
|
238
|
+
fallback,
|
|
239
|
+
onError,
|
|
240
|
+
capture = true,
|
|
241
|
+
captureComponentStack = true,
|
|
242
|
+
beforeReactCapture,
|
|
243
|
+
tags = {},
|
|
244
|
+
context = {}
|
|
245
|
+
} = options;
|
|
222
246
|
const Wrapped = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
223
247
|
ErrorBoundary,
|
|
224
248
|
{
|
|
225
249
|
fallback,
|
|
226
250
|
onError,
|
|
227
251
|
capture,
|
|
252
|
+
captureComponentStack,
|
|
253
|
+
beforeReactCapture,
|
|
228
254
|
tags,
|
|
229
255
|
context,
|
|
230
256
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component2, { ...props })
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/context.tsx","../src/ErrorBoundary.tsx","../src/hooks.ts"],"sourcesContent":["/**\n * @error-explorer/react\n * Error Explorer SDK for React - Automatic error tracking with React integration\n */\n\n// Import for default export\nimport { ErrorExplorerProvider as Provider } from './context';\n\n// Provider and initialization\nexport { ErrorExplorerProvider, ErrorExplorerContext, initErrorExplorer } from './context';\n\n// Error Boundary\nexport { ErrorBoundary, withErrorBoundary, useErrorBoundary } from './ErrorBoundary';\n\n// Hooks\nexport {\n useErrorExplorer,\n useErrorHandler,\n useUserContext,\n useActionTracker,\n useComponentBreadcrumbs,\n} from './hooks';\n\n// Types\nexport type {\n ReactErrorExplorerOptions,\n ReactComponentContext,\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n ErrorExplorerProviderProps,\n ErrorExplorerContextValue,\n WithErrorBoundaryOptions,\n InitOptions,\n UserContext,\n Breadcrumb,\n CaptureContext,\n} from './types';\n\n// Re-export ErrorExplorer for direct access\nexport { ErrorExplorer } from '@error-explorer/browser';\n\n// Default export is the provider for convenience\nexport default Provider;\n","/**\n * React Context Provider for Error Explorer\n */\n\nimport React, { createContext, useEffect, useState, useMemo, type ReactNode } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport type { ReactErrorExplorerOptions, ErrorExplorerContextValue } from './types';\n\n/**\n * React Context for Error Explorer\n */\nexport const ErrorExplorerContext = createContext<ErrorExplorerContextValue | null>(null);\n\n/**\n * Error Explorer Provider Component\n *\n * Initializes the Error Explorer SDK and provides context to child components.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <ErrorExplorerProvider\n * options={{\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * }}\n * >\n * <MainContent />\n * </ErrorExplorerProvider>\n * );\n * }\n * ```\n */\nexport function ErrorExplorerProvider({\n options,\n children,\n}: {\n options: ReactErrorExplorerOptions;\n children: ReactNode;\n}) {\n const [isInitialized, setIsInitialized] = useState(false);\n\n // Initialize on mount\n useEffect(() => {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n setIsInitialized(true);\n } else {\n setIsInitialized(true);\n }\n\n // Cleanup on unmount\n return () => {\n // Don't close on unmount as other components might still need it\n // ErrorExplorer.close();\n };\n }, []); // Only run once on mount\n\n // Create stable context value\n const contextValue = useMemo<ErrorExplorerContextValue>(\n () => ({\n isInitialized,\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n }),\n [isInitialized]\n );\n\n return (\n <ErrorExplorerContext.Provider value={contextValue}>\n {children}\n </ErrorExplorerContext.Provider>\n );\n}\n\n/**\n * Initialize Error Explorer directly (without provider)\n *\n * Use this if you don't need the React Context and just want to initialize\n * the SDK globally.\n *\n * @example\n * ```tsx\n * // In your entry file (main.tsx)\n * import { initErrorExplorer } from '@error-explorer/react';\n *\n * initErrorExplorer({\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * });\n *\n * ReactDOM.createRoot(root).render(<App />);\n * ```\n */\nexport function initErrorExplorer(options: ReactErrorExplorerOptions): void {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n }\n}\n","/**\n * ErrorBoundary component for React\n * Catches errors in child components and reports them to Error Explorer\n */\n\nimport React, { Component, type ReactNode, type ComponentType } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type {\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n WithErrorBoundaryOptions,\n} from './types';\n\n/**\n * Default fallback component\n */\nconst DefaultFallback: React.FC<FallbackProps> = ({ error, resetErrorBoundary }) => (\n <div\n role=\"alert\"\n style={{\n padding: '20px',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n backgroundColor: '#f8d7da',\n color: '#721c24',\n }}\n >\n <h2 style={{ margin: '0 0 10px 0' }}>Something went wrong</h2>\n <pre style={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n backgroundColor: 'rgba(0,0,0,0.1)',\n padding: '10px',\n borderRadius: '4px',\n fontSize: '14px',\n }}>\n {error.message}\n </pre>\n <button\n onClick={resetErrorBoundary}\n style={{\n marginTop: '10px',\n padding: '8px 16px',\n backgroundColor: '#721c24',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Try again\n </button>\n </div>\n);\n\n/**\n * ErrorBoundary class component\n *\n * React Error Boundaries must be class components - there's no hook equivalent.\n *\n * @example\n * ```tsx\n * <ErrorBoundary fallback={<ErrorFallback />}>\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n *\n * @example\n * With render prop fallback:\n * ```tsx\n * <ErrorBoundary\n * fallback={({ error, resetErrorBoundary }) => (\n * <div>\n * <p>Error: {error.message}</p>\n * <button onClick={resetErrorBoundary}>Retry</button>\n * </div>\n * )}\n * >\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n static defaultProps = {\n capture: true,\n tags: {},\n context: {},\n };\n\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.setState({ errorInfo });\n\n const { capture = true, tags = {}, context = {}, onError } = this.props;\n\n // Call user's error handler\n if (onError) {\n onError(error, errorInfo);\n }\n\n // Capture to Error Explorer\n if (capture) {\n ErrorExplorer.captureException(error, {\n tags: {\n 'react.errorBoundary': 'true',\n ...tags,\n },\n extra: {\n componentStack: errorInfo.componentStack,\n ...context,\n },\n });\n }\n }\n\n componentDidUpdate(prevProps: ErrorBoundaryProps): void {\n const { resetKeys } = this.props;\n const { hasError } = this.state;\n\n // Reset if resetKeys changed\n if (hasError && resetKeys && prevProps.resetKeys) {\n const hasResetKeyChanged = resetKeys.some(\n (key, index) => key !== prevProps.resetKeys?.[index]\n );\n\n if (hasResetKeyChanged) {\n this.reset();\n }\n }\n }\n\n reset = (): void => {\n const { onReset } = this.props;\n\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n\n if (onReset) {\n onReset();\n }\n };\n\n render(): ReactNode {\n const { hasError, error, errorInfo } = this.state;\n const { children, fallback } = this.props;\n\n if (hasError && error) {\n const fallbackProps: FallbackProps = {\n error,\n errorInfo,\n resetErrorBoundary: this.reset,\n };\n\n // Render function fallback\n if (typeof fallback === 'function') {\n return fallback(fallbackProps);\n }\n\n // Static fallback\n if (fallback) {\n return fallback;\n }\n\n // Default fallback\n return <DefaultFallback {...fallbackProps} />;\n }\n\n return children;\n }\n}\n\n/**\n * Higher-order component to wrap a component with ErrorBoundary\n *\n * @example\n * ```tsx\n * const SafeComponent = withErrorBoundary(MyComponent, {\n * fallback: <ErrorFallback />,\n * onError: (error) => console.error(error),\n * });\n * ```\n */\nexport function withErrorBoundary<P extends object>(\n Component: ComponentType<P>,\n options: WithErrorBoundaryOptions = {}\n): ComponentType<P> {\n const { fallback, onError, capture = true, tags = {}, context = {} } = options;\n\n const Wrapped: React.FC<P> = (props) => (\n <ErrorBoundary\n fallback={fallback}\n onError={onError}\n capture={capture}\n tags={tags}\n context={context}\n >\n <Component {...props} />\n </ErrorBoundary>\n );\n\n // Preserve display name for debugging\n const displayName = Component.displayName || Component.name || 'Component';\n Wrapped.displayName = `withErrorBoundary(${displayName})`;\n\n return Wrapped;\n}\n\n/**\n * useErrorBoundary hook for functional components\n *\n * Note: This doesn't create an error boundary - those must be class components.\n * Instead, this provides a way to show/trigger the nearest error boundary.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { showBoundary } = useErrorBoundary();\n *\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * showBoundary(error);\n * }\n * };\n * }\n * ```\n */\nexport function useErrorBoundary() {\n const [error, setError] = React.useState<Error | null>(null);\n\n // If there's an error, throw it to be caught by the nearest error boundary\n if (error) {\n throw error;\n }\n\n return {\n /**\n * Trigger the nearest error boundary with the given error\n */\n showBoundary: (err: Error) => setError(err),\n\n /**\n * Reset the error state\n */\n resetBoundary: () => setError(null),\n };\n}\n","/**\n * React Hooks for Error Explorer\n */\n\nimport { useContext, useEffect, useCallback, useRef } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport { ErrorExplorerContext } from './context';\n\n/**\n * Use Error Explorer instance\n *\n * Returns the Error Explorer SDK methods for capturing errors and managing context.\n *\n * @example\n * ```tsx\n * const { captureException, addBreadcrumb, setUser } = useErrorExplorer();\n *\n * try {\n * await riskyOperation();\n * } catch (error) {\n * captureException(error);\n * }\n * ```\n */\nexport function useErrorExplorer() {\n // Try to get from context first (if using provider)\n const contextValue = useContext(ErrorExplorerContext);\n\n // If context is available and initialized, use it\n if (contextValue?.isInitialized) {\n return contextValue;\n }\n\n // Fall back to singleton\n return {\n isInitialized: ErrorExplorer.isInitialized(),\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n };\n}\n\n/**\n * Error handler hook for async operations\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { handleError, wrapAsync } = useErrorHandler();\n *\n * // Option 1: Wrap async function\n * const safeSubmit = wrapAsync(async () => {\n * await api.submit(data);\n * });\n *\n * // Option 2: Manual handling\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * handleError(error, { tags: { operation: 'risky' } });\n * }\n * };\n * }\n * ```\n */\nexport function useErrorHandler(defaultContext?: CaptureContext) {\n const { captureException } = useErrorExplorer();\n\n /**\n * Handle an error with optional context\n */\n const handleError = useCallback(\n (error: unknown, context?: CaptureContext): Error => {\n const err = error instanceof Error ? error : new Error(String(error));\n\n captureException(err, {\n ...defaultContext,\n ...context,\n tags: {\n ...defaultContext?.tags,\n ...context?.tags,\n },\n extra: {\n ...defaultContext?.extra,\n ...context?.extra,\n },\n });\n\n return err;\n },\n [captureException, defaultContext]\n );\n\n /**\n * Wrap an async function with error handling\n */\n const wrapAsync = useCallback(\n <T extends (...args: any[]) => Promise<any>>(\n fn: T,\n context?: CaptureContext\n ): ((...args: Parameters<T>) => Promise<Awaited<ReturnType<T>> | undefined>) => {\n return async (...args: Parameters<T>) => {\n try {\n return await fn(...args);\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n };\n },\n [handleError]\n );\n\n /**\n * Create a try-catch wrapper that captures errors\n */\n const tryCatch = useCallback(\n <T>(fn: () => T, context?: CaptureContext): T | undefined => {\n try {\n return fn();\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n },\n [handleError]\n );\n\n return {\n handleError,\n wrapAsync,\n tryCatch,\n };\n}\n\n/**\n * User context hook\n *\n * Sets the user context and cleans up on unmount.\n *\n * @example\n * ```tsx\n * function App() {\n * const user = useCurrentUser();\n *\n * useUserContext(user ? {\n * id: user.id,\n * email: user.email,\n * name: user.name,\n * } : null);\n *\n * return <MainContent />;\n * }\n * ```\n */\nexport function useUserContext(user: UserContext | null) {\n const { setUser, clearUser } = useErrorExplorer();\n const previousUser = useRef<UserContext | null>(null);\n\n useEffect(() => {\n // Only update if user changed\n if (JSON.stringify(user) !== JSON.stringify(previousUser.current)) {\n if (user) {\n setUser(user);\n } else {\n clearUser();\n }\n previousUser.current = user;\n }\n }, [user, setUser, clearUser]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearUser();\n };\n }, [clearUser]);\n\n return { setUser, clearUser };\n}\n\n/**\n * Action tracker hook for user interactions\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { trackAction, trackInteraction } = useActionTracker();\n *\n * const handleSubmit = () => {\n * trackAction('form_submitted', { formId: 'contact' });\n * // ... actual submit logic\n * };\n *\n * return (\n * <button\n * onClick={() => {\n * trackInteraction('submit-button', 'click');\n * handleSubmit();\n * }}\n * >\n * Submit\n * </button>\n * );\n * }\n * ```\n */\nexport function useActionTracker(componentName?: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n /**\n * Track a user action\n */\n const trackAction = useCallback(\n (action: string, data?: Record<string, unknown>) => {\n addBreadcrumb({\n type: 'user-action',\n category: 'action',\n message: action,\n level: 'info',\n data: {\n component: componentName,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n /**\n * Track a UI interaction\n */\n const trackInteraction = useCallback(\n (\n element: string,\n action: 'click' | 'input' | 'focus' | 'blur' | 'submit',\n data?: Record<string, unknown>\n ) => {\n addBreadcrumb({\n type: 'user-action',\n category: `ui.${action}`,\n message: `${action} on ${element}`,\n level: 'info',\n data: {\n component: componentName,\n element,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n return {\n trackAction,\n trackInteraction,\n };\n}\n\n/**\n * Component lifecycle tracking hook\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * useComponentBreadcrumbs('MyComponent');\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useComponentBreadcrumbs(componentName: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n useEffect(() => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} mounted`,\n level: 'debug',\n });\n\n return () => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} unmounted`,\n level: 'debug',\n });\n };\n }, [componentName, addBreadcrumb]);\n}\n"],"mappings":"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","names":["import_react","import_browser","import_jsx_runtime","Component","React","import_react","import_browser","import_browser"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context.tsx","../src/ErrorBoundary.tsx","../src/hooks.ts"],"sourcesContent":["/**\n * @error-explorer/react\n * Error Explorer SDK for React - Automatic error tracking with React integration\n */\n\n// Import for default export\nimport { ErrorExplorerProvider as Provider } from './context';\n\n// Provider and initialization\nexport { ErrorExplorerProvider, ErrorExplorerContext, initErrorExplorer } from './context';\n\n// Error Boundary\nexport { ErrorBoundary, withErrorBoundary, useErrorBoundary } from './ErrorBoundary';\n\n// Hooks\nexport {\n useErrorExplorer,\n useErrorHandler,\n useUserContext,\n useActionTracker,\n useComponentBreadcrumbs,\n} from './hooks';\n\n// Types\nexport type {\n ReactErrorExplorerOptions,\n ReactComponentContext,\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n ErrorExplorerProviderProps,\n ErrorExplorerContextValue,\n WithErrorBoundaryOptions,\n InitOptions,\n UserContext,\n Breadcrumb,\n CaptureContext,\n} from './types';\n\n// Re-export ErrorExplorer for direct access\nexport { ErrorExplorer } from '@error-explorer/browser';\n\n// Default export is the provider for convenience\nexport default Provider;\n","/**\n * React Context Provider for Error Explorer\n */\n\nimport React, { createContext, useEffect, useState, useMemo, type ReactNode } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport type { ReactErrorExplorerOptions, ErrorExplorerContextValue } from './types';\n\n/**\n * React Context for Error Explorer\n */\nexport const ErrorExplorerContext = createContext<ErrorExplorerContextValue | null>(null);\n\n/**\n * Error Explorer Provider Component\n *\n * Initializes the Error Explorer SDK and provides context to child components.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <ErrorExplorerProvider\n * options={{\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * }}\n * >\n * <MainContent />\n * </ErrorExplorerProvider>\n * );\n * }\n * ```\n */\nexport function ErrorExplorerProvider({\n options,\n children,\n}: {\n options: ReactErrorExplorerOptions;\n children: ReactNode;\n}) {\n const [isInitialized, setIsInitialized] = useState(false);\n\n // Initialize on mount\n useEffect(() => {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n setIsInitialized(true);\n } else {\n setIsInitialized(true);\n }\n\n // Cleanup on unmount\n return () => {\n // Don't close on unmount as other components might still need it\n // ErrorExplorer.close();\n };\n }, []); // Only run once on mount\n\n // Create stable context value\n const contextValue = useMemo<ErrorExplorerContextValue>(\n () => ({\n isInitialized,\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n }),\n [isInitialized]\n );\n\n return (\n <ErrorExplorerContext.Provider value={contextValue}>\n {children}\n </ErrorExplorerContext.Provider>\n );\n}\n\n/**\n * Initialize Error Explorer directly (without provider)\n *\n * Use this if you don't need the React Context and just want to initialize\n * the SDK globally.\n *\n * @example\n * ```tsx\n * // In your entry file (main.tsx)\n * import { initErrorExplorer } from '@error-explorer/react';\n *\n * initErrorExplorer({\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * });\n *\n * ReactDOM.createRoot(root).render(<App />);\n * ```\n */\nexport function initErrorExplorer(options: ReactErrorExplorerOptions): void {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n }\n}\n","/**\n * ErrorBoundary component for React\n * Catches errors in child components and reports them to Error Explorer\n */\n\nimport React, { Component, type ReactNode, type ComponentType } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type {\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n WithErrorBoundaryOptions,\n} from './types';\n\n/**\n * Default fallback component\n */\nconst DefaultFallback: React.FC<FallbackProps> = ({ error, resetErrorBoundary }) => (\n <div\n role=\"alert\"\n style={{\n padding: '20px',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n backgroundColor: '#f8d7da',\n color: '#721c24',\n }}\n >\n <h2 style={{ margin: '0 0 10px 0' }}>Something went wrong</h2>\n <pre style={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n backgroundColor: 'rgba(0,0,0,0.1)',\n padding: '10px',\n borderRadius: '4px',\n fontSize: '14px',\n }}>\n {error.message}\n </pre>\n <button\n onClick={resetErrorBoundary}\n style={{\n marginTop: '10px',\n padding: '8px 16px',\n backgroundColor: '#721c24',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Try again\n </button>\n </div>\n);\n\n/**\n * ErrorBoundary class component\n *\n * React Error Boundaries must be class components - there's no hook equivalent.\n *\n * @example\n * ```tsx\n * <ErrorBoundary fallback={<ErrorFallback />}>\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n *\n * @example\n * With render prop fallback:\n * ```tsx\n * <ErrorBoundary\n * fallback={({ error, resetErrorBoundary }) => (\n * <div>\n * <p>Error: {error.message}</p>\n * <button onClick={resetErrorBoundary}>Retry</button>\n * </div>\n * )}\n * >\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n static defaultProps = {\n capture: true,\n captureComponentStack: true,\n tags: {},\n context: {},\n };\n\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.setState({ errorInfo });\n\n const {\n capture = true,\n captureComponentStack = true,\n beforeReactCapture,\n tags = {},\n context = {},\n onError,\n } = this.props;\n\n // Call user's error handler\n if (onError) {\n onError(error, errorInfo);\n }\n\n // Check if capture is enabled\n if (!capture) {\n return;\n }\n\n // Call beforeReactCapture hook - if it returns false, skip capturing\n if (beforeReactCapture) {\n const shouldCapture = beforeReactCapture(error, errorInfo);\n if (shouldCapture === false) {\n return;\n }\n }\n\n // Build extra context\n const extra: Record<string, unknown> = { ...context };\n\n // Only include component stack if enabled\n if (captureComponentStack && errorInfo.componentStack) {\n extra.componentStack = errorInfo.componentStack;\n }\n\n // Capture to Error Explorer\n ErrorExplorer.captureException(error, {\n tags: {\n 'react.errorBoundary': 'true',\n ...tags,\n },\n extra,\n });\n }\n\n componentDidUpdate(prevProps: ErrorBoundaryProps): void {\n const { resetKeys } = this.props;\n const { hasError } = this.state;\n\n // Reset if resetKeys changed\n if (hasError && resetKeys && prevProps.resetKeys) {\n const hasResetKeyChanged = resetKeys.some(\n (key, index) => key !== prevProps.resetKeys?.[index]\n );\n\n if (hasResetKeyChanged) {\n this.reset();\n }\n }\n }\n\n reset = (): void => {\n const { onReset } = this.props;\n\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n\n if (onReset) {\n onReset();\n }\n };\n\n render(): ReactNode {\n const { hasError, error, errorInfo } = this.state;\n const { children, fallback } = this.props;\n\n if (hasError && error) {\n const fallbackProps: FallbackProps = {\n error,\n errorInfo,\n resetErrorBoundary: this.reset,\n };\n\n // Render function fallback\n if (typeof fallback === 'function') {\n return fallback(fallbackProps);\n }\n\n // Static fallback\n if (fallback) {\n return fallback;\n }\n\n // Default fallback\n return <DefaultFallback {...fallbackProps} />;\n }\n\n return children;\n }\n}\n\n/**\n * Higher-order component to wrap a component with ErrorBoundary\n *\n * @example\n * ```tsx\n * const SafeComponent = withErrorBoundary(MyComponent, {\n * fallback: <ErrorFallback />,\n * onError: (error) => console.error(error),\n * });\n * ```\n */\nexport function withErrorBoundary<P extends object>(\n Component: ComponentType<P>,\n options: WithErrorBoundaryOptions = {}\n): ComponentType<P> {\n const {\n fallback,\n onError,\n capture = true,\n captureComponentStack = true,\n beforeReactCapture,\n tags = {},\n context = {},\n } = options;\n\n const Wrapped: React.FC<P> = (props) => (\n <ErrorBoundary\n fallback={fallback}\n onError={onError}\n capture={capture}\n captureComponentStack={captureComponentStack}\n beforeReactCapture={beforeReactCapture}\n tags={tags}\n context={context}\n >\n <Component {...props} />\n </ErrorBoundary>\n );\n\n // Preserve display name for debugging\n const displayName = Component.displayName || Component.name || 'Component';\n Wrapped.displayName = `withErrorBoundary(${displayName})`;\n\n return Wrapped;\n}\n\n/**\n * useErrorBoundary hook for functional components\n *\n * Note: This doesn't create an error boundary - those must be class components.\n * Instead, this provides a way to show/trigger the nearest error boundary.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { showBoundary } = useErrorBoundary();\n *\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * showBoundary(error);\n * }\n * };\n * }\n * ```\n */\nexport function useErrorBoundary() {\n const [error, setError] = React.useState<Error | null>(null);\n\n // If there's an error, throw it to be caught by the nearest error boundary\n if (error) {\n throw error;\n }\n\n return {\n /**\n * Trigger the nearest error boundary with the given error\n */\n showBoundary: (err: Error) => setError(err),\n\n /**\n * Reset the error state\n */\n resetBoundary: () => setError(null),\n };\n}\n","/**\n * React Hooks for Error Explorer\n */\n\nimport { useContext, useEffect, useCallback, useRef } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport { ErrorExplorerContext } from './context';\n\n/**\n * Use Error Explorer instance\n *\n * Returns the Error Explorer SDK methods for capturing errors and managing context.\n *\n * @example\n * ```tsx\n * const { captureException, addBreadcrumb, setUser } = useErrorExplorer();\n *\n * try {\n * await riskyOperation();\n * } catch (error) {\n * captureException(error);\n * }\n * ```\n */\nexport function useErrorExplorer() {\n // Try to get from context first (if using provider)\n const contextValue = useContext(ErrorExplorerContext);\n\n // If context is available and initialized, use it\n if (contextValue?.isInitialized) {\n return contextValue;\n }\n\n // Fall back to singleton\n return {\n isInitialized: ErrorExplorer.isInitialized(),\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n };\n}\n\n/**\n * Error handler hook for async operations\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { handleError, wrapAsync } = useErrorHandler();\n *\n * // Option 1: Wrap async function\n * const safeSubmit = wrapAsync(async () => {\n * await api.submit(data);\n * });\n *\n * // Option 2: Manual handling\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * handleError(error, { tags: { operation: 'risky' } });\n * }\n * };\n * }\n * ```\n */\nexport function useErrorHandler(defaultContext?: CaptureContext) {\n const { captureException } = useErrorExplorer();\n\n /**\n * Handle an error with optional context\n */\n const handleError = useCallback(\n (error: unknown, context?: CaptureContext): Error => {\n const err = error instanceof Error ? error : new Error(String(error));\n\n captureException(err, {\n ...defaultContext,\n ...context,\n tags: {\n ...defaultContext?.tags,\n ...context?.tags,\n },\n extra: {\n ...defaultContext?.extra,\n ...context?.extra,\n },\n });\n\n return err;\n },\n [captureException, defaultContext]\n );\n\n /**\n * Wrap an async function with error handling\n */\n const wrapAsync = useCallback(\n <T extends (...args: any[]) => Promise<any>>(\n fn: T,\n context?: CaptureContext\n ): ((...args: Parameters<T>) => Promise<Awaited<ReturnType<T>> | undefined>) => {\n return async (...args: Parameters<T>) => {\n try {\n return await fn(...args);\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n };\n },\n [handleError]\n );\n\n /**\n * Create a try-catch wrapper that captures errors\n */\n const tryCatch = useCallback(\n <T>(fn: () => T, context?: CaptureContext): T | undefined => {\n try {\n return fn();\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n },\n [handleError]\n );\n\n return {\n handleError,\n wrapAsync,\n tryCatch,\n };\n}\n\n/**\n * User context hook\n *\n * Sets the user context and cleans up on unmount.\n *\n * @example\n * ```tsx\n * function App() {\n * const user = useCurrentUser();\n *\n * useUserContext(user ? {\n * id: user.id,\n * email: user.email,\n * name: user.name,\n * } : null);\n *\n * return <MainContent />;\n * }\n * ```\n */\nexport function useUserContext(user: UserContext | null) {\n const { setUser, clearUser } = useErrorExplorer();\n const previousUser = useRef<UserContext | null>(null);\n\n useEffect(() => {\n // Only update if user changed\n if (JSON.stringify(user) !== JSON.stringify(previousUser.current)) {\n if (user) {\n setUser(user);\n } else {\n clearUser();\n }\n previousUser.current = user;\n }\n }, [user, setUser, clearUser]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearUser();\n };\n }, [clearUser]);\n\n return { setUser, clearUser };\n}\n\n/**\n * Action tracker hook for user interactions\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { trackAction, trackInteraction } = useActionTracker();\n *\n * const handleSubmit = () => {\n * trackAction('form_submitted', { formId: 'contact' });\n * // ... actual submit logic\n * };\n *\n * return (\n * <button\n * onClick={() => {\n * trackInteraction('submit-button', 'click');\n * handleSubmit();\n * }}\n * >\n * Submit\n * </button>\n * );\n * }\n * ```\n */\nexport function useActionTracker(componentName?: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n /**\n * Track a user action\n */\n const trackAction = useCallback(\n (action: string, data?: Record<string, unknown>) => {\n addBreadcrumb({\n type: 'user-action',\n category: 'action',\n message: action,\n level: 'info',\n data: {\n component: componentName,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n /**\n * Track a UI interaction\n */\n const trackInteraction = useCallback(\n (\n element: string,\n action: 'click' | 'input' | 'focus' | 'blur' | 'submit',\n data?: Record<string, unknown>\n ) => {\n addBreadcrumb({\n type: 'user-action',\n category: `ui.${action}`,\n message: `${action} on ${element}`,\n level: 'info',\n data: {\n component: componentName,\n element,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n return {\n trackAction,\n trackInteraction,\n };\n}\n\n/**\n * Component lifecycle tracking hook\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * useComponentBreadcrumbs('MyComponent');\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useComponentBreadcrumbs(componentName: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n useEffect(() => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} mounted`,\n level: 'debug',\n });\n\n return () => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} unmounted`,\n level: 'debug',\n });\n };\n }, [componentName, addBreadcrumb]);\n}\n"],"mappings":"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","names":["import_react","import_browser","import_jsx_runtime","Component","React","import_react","import_browser","import_browser"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -64,6 +64,16 @@ interface ErrorBoundaryProps {
|
|
|
64
64
|
* @default true
|
|
65
65
|
*/
|
|
66
66
|
capture?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to capture React component stack traces
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
captureComponentStack?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Hook called before capturing a React error
|
|
74
|
+
* Return false to skip capturing
|
|
75
|
+
*/
|
|
76
|
+
beforeReactCapture?: (error: Error, errorInfo: React.ErrorInfo) => boolean;
|
|
67
77
|
/**
|
|
68
78
|
* Additional tags to add when capturing
|
|
69
79
|
*/
|
|
@@ -185,6 +195,16 @@ interface WithErrorBoundaryOptions {
|
|
|
185
195
|
* @default true
|
|
186
196
|
*/
|
|
187
197
|
capture?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Whether to capture React component stack traces
|
|
200
|
+
* @default true
|
|
201
|
+
*/
|
|
202
|
+
captureComponentStack?: boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Hook called before capturing a React error
|
|
205
|
+
* Return false to skip capturing
|
|
206
|
+
*/
|
|
207
|
+
beforeReactCapture?: (error: Error, errorInfo: React.ErrorInfo) => boolean;
|
|
188
208
|
/**
|
|
189
209
|
* Additional tags to add when capturing
|
|
190
210
|
*/
|
|
@@ -282,6 +302,7 @@ declare function initErrorExplorer(options: ReactErrorExplorerOptions): void;
|
|
|
282
302
|
declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
283
303
|
static defaultProps: {
|
|
284
304
|
capture: boolean;
|
|
305
|
+
captureComponentStack: boolean;
|
|
285
306
|
tags: {};
|
|
286
307
|
context: {};
|
|
287
308
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -64,6 +64,16 @@ interface ErrorBoundaryProps {
|
|
|
64
64
|
* @default true
|
|
65
65
|
*/
|
|
66
66
|
capture?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to capture React component stack traces
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
captureComponentStack?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Hook called before capturing a React error
|
|
74
|
+
* Return false to skip capturing
|
|
75
|
+
*/
|
|
76
|
+
beforeReactCapture?: (error: Error, errorInfo: React.ErrorInfo) => boolean;
|
|
67
77
|
/**
|
|
68
78
|
* Additional tags to add when capturing
|
|
69
79
|
*/
|
|
@@ -185,6 +195,16 @@ interface WithErrorBoundaryOptions {
|
|
|
185
195
|
* @default true
|
|
186
196
|
*/
|
|
187
197
|
capture?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Whether to capture React component stack traces
|
|
200
|
+
* @default true
|
|
201
|
+
*/
|
|
202
|
+
captureComponentStack?: boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Hook called before capturing a React error
|
|
205
|
+
* Return false to skip capturing
|
|
206
|
+
*/
|
|
207
|
+
beforeReactCapture?: (error: Error, errorInfo: React.ErrorInfo) => boolean;
|
|
188
208
|
/**
|
|
189
209
|
* Additional tags to add when capturing
|
|
190
210
|
*/
|
|
@@ -282,6 +302,7 @@ declare function initErrorExplorer(options: ReactErrorExplorerOptions): void;
|
|
|
282
302
|
declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
283
303
|
static defaultProps: {
|
|
284
304
|
capture: boolean;
|
|
305
|
+
captureComponentStack: boolean;
|
|
285
306
|
tags: {};
|
|
286
307
|
context: {};
|
|
287
308
|
};
|
package/dist/index.js
CHANGED
|
@@ -115,22 +115,37 @@ var ErrorBoundary = class extends Component {
|
|
|
115
115
|
}
|
|
116
116
|
componentDidCatch(error, errorInfo) {
|
|
117
117
|
this.setState({ errorInfo });
|
|
118
|
-
const {
|
|
118
|
+
const {
|
|
119
|
+
capture = true,
|
|
120
|
+
captureComponentStack = true,
|
|
121
|
+
beforeReactCapture,
|
|
122
|
+
tags = {},
|
|
123
|
+
context = {},
|
|
124
|
+
onError
|
|
125
|
+
} = this.props;
|
|
119
126
|
if (onError) {
|
|
120
127
|
onError(error, errorInfo);
|
|
121
128
|
}
|
|
122
|
-
if (capture) {
|
|
123
|
-
|
|
124
|
-
tags: {
|
|
125
|
-
"react.errorBoundary": "true",
|
|
126
|
-
...tags
|
|
127
|
-
},
|
|
128
|
-
extra: {
|
|
129
|
-
componentStack: errorInfo.componentStack,
|
|
130
|
-
...context
|
|
131
|
-
}
|
|
132
|
-
});
|
|
129
|
+
if (!capture) {
|
|
130
|
+
return;
|
|
133
131
|
}
|
|
132
|
+
if (beforeReactCapture) {
|
|
133
|
+
const shouldCapture = beforeReactCapture(error, errorInfo);
|
|
134
|
+
if (shouldCapture === false) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const extra = { ...context };
|
|
139
|
+
if (captureComponentStack && errorInfo.componentStack) {
|
|
140
|
+
extra.componentStack = errorInfo.componentStack;
|
|
141
|
+
}
|
|
142
|
+
ErrorExplorer2.captureException(error, {
|
|
143
|
+
tags: {
|
|
144
|
+
"react.errorBoundary": "true",
|
|
145
|
+
...tags
|
|
146
|
+
},
|
|
147
|
+
extra
|
|
148
|
+
});
|
|
134
149
|
}
|
|
135
150
|
componentDidUpdate(prevProps) {
|
|
136
151
|
const { resetKeys } = this.props;
|
|
@@ -166,17 +181,28 @@ var ErrorBoundary = class extends Component {
|
|
|
166
181
|
};
|
|
167
182
|
ErrorBoundary.defaultProps = {
|
|
168
183
|
capture: true,
|
|
184
|
+
captureComponentStack: true,
|
|
169
185
|
tags: {},
|
|
170
186
|
context: {}
|
|
171
187
|
};
|
|
172
188
|
function withErrorBoundary(Component2, options = {}) {
|
|
173
|
-
const {
|
|
189
|
+
const {
|
|
190
|
+
fallback,
|
|
191
|
+
onError,
|
|
192
|
+
capture = true,
|
|
193
|
+
captureComponentStack = true,
|
|
194
|
+
beforeReactCapture,
|
|
195
|
+
tags = {},
|
|
196
|
+
context = {}
|
|
197
|
+
} = options;
|
|
174
198
|
const Wrapped = (props) => /* @__PURE__ */ jsx2(
|
|
175
199
|
ErrorBoundary,
|
|
176
200
|
{
|
|
177
201
|
fallback,
|
|
178
202
|
onError,
|
|
179
203
|
capture,
|
|
204
|
+
captureComponentStack,
|
|
205
|
+
beforeReactCapture,
|
|
180
206
|
tags,
|
|
181
207
|
context,
|
|
182
208
|
children: /* @__PURE__ */ jsx2(Component2, { ...props })
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.tsx","../src/ErrorBoundary.tsx","../src/hooks.ts","../src/index.ts"],"sourcesContent":["/**\n * React Context Provider for Error Explorer\n */\n\nimport React, { createContext, useEffect, useState, useMemo, type ReactNode } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport type { ReactErrorExplorerOptions, ErrorExplorerContextValue } from './types';\n\n/**\n * React Context for Error Explorer\n */\nexport const ErrorExplorerContext = createContext<ErrorExplorerContextValue | null>(null);\n\n/**\n * Error Explorer Provider Component\n *\n * Initializes the Error Explorer SDK and provides context to child components.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <ErrorExplorerProvider\n * options={{\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * }}\n * >\n * <MainContent />\n * </ErrorExplorerProvider>\n * );\n * }\n * ```\n */\nexport function ErrorExplorerProvider({\n options,\n children,\n}: {\n options: ReactErrorExplorerOptions;\n children: ReactNode;\n}) {\n const [isInitialized, setIsInitialized] = useState(false);\n\n // Initialize on mount\n useEffect(() => {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n setIsInitialized(true);\n } else {\n setIsInitialized(true);\n }\n\n // Cleanup on unmount\n return () => {\n // Don't close on unmount as other components might still need it\n // ErrorExplorer.close();\n };\n }, []); // Only run once on mount\n\n // Create stable context value\n const contextValue = useMemo<ErrorExplorerContextValue>(\n () => ({\n isInitialized,\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n }),\n [isInitialized]\n );\n\n return (\n <ErrorExplorerContext.Provider value={contextValue}>\n {children}\n </ErrorExplorerContext.Provider>\n );\n}\n\n/**\n * Initialize Error Explorer directly (without provider)\n *\n * Use this if you don't need the React Context and just want to initialize\n * the SDK globally.\n *\n * @example\n * ```tsx\n * // In your entry file (main.tsx)\n * import { initErrorExplorer } from '@error-explorer/react';\n *\n * initErrorExplorer({\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * });\n *\n * ReactDOM.createRoot(root).render(<App />);\n * ```\n */\nexport function initErrorExplorer(options: ReactErrorExplorerOptions): void {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n }\n}\n","/**\n * ErrorBoundary component for React\n * Catches errors in child components and reports them to Error Explorer\n */\n\nimport React, { Component, type ReactNode, type ComponentType } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type {\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n WithErrorBoundaryOptions,\n} from './types';\n\n/**\n * Default fallback component\n */\nconst DefaultFallback: React.FC<FallbackProps> = ({ error, resetErrorBoundary }) => (\n <div\n role=\"alert\"\n style={{\n padding: '20px',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n backgroundColor: '#f8d7da',\n color: '#721c24',\n }}\n >\n <h2 style={{ margin: '0 0 10px 0' }}>Something went wrong</h2>\n <pre style={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n backgroundColor: 'rgba(0,0,0,0.1)',\n padding: '10px',\n borderRadius: '4px',\n fontSize: '14px',\n }}>\n {error.message}\n </pre>\n <button\n onClick={resetErrorBoundary}\n style={{\n marginTop: '10px',\n padding: '8px 16px',\n backgroundColor: '#721c24',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Try again\n </button>\n </div>\n);\n\n/**\n * ErrorBoundary class component\n *\n * React Error Boundaries must be class components - there's no hook equivalent.\n *\n * @example\n * ```tsx\n * <ErrorBoundary fallback={<ErrorFallback />}>\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n *\n * @example\n * With render prop fallback:\n * ```tsx\n * <ErrorBoundary\n * fallback={({ error, resetErrorBoundary }) => (\n * <div>\n * <p>Error: {error.message}</p>\n * <button onClick={resetErrorBoundary}>Retry</button>\n * </div>\n * )}\n * >\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n static defaultProps = {\n capture: true,\n tags: {},\n context: {},\n };\n\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.setState({ errorInfo });\n\n const { capture = true, tags = {}, context = {}, onError } = this.props;\n\n // Call user's error handler\n if (onError) {\n onError(error, errorInfo);\n }\n\n // Capture to Error Explorer\n if (capture) {\n ErrorExplorer.captureException(error, {\n tags: {\n 'react.errorBoundary': 'true',\n ...tags,\n },\n extra: {\n componentStack: errorInfo.componentStack,\n ...context,\n },\n });\n }\n }\n\n componentDidUpdate(prevProps: ErrorBoundaryProps): void {\n const { resetKeys } = this.props;\n const { hasError } = this.state;\n\n // Reset if resetKeys changed\n if (hasError && resetKeys && prevProps.resetKeys) {\n const hasResetKeyChanged = resetKeys.some(\n (key, index) => key !== prevProps.resetKeys?.[index]\n );\n\n if (hasResetKeyChanged) {\n this.reset();\n }\n }\n }\n\n reset = (): void => {\n const { onReset } = this.props;\n\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n\n if (onReset) {\n onReset();\n }\n };\n\n render(): ReactNode {\n const { hasError, error, errorInfo } = this.state;\n const { children, fallback } = this.props;\n\n if (hasError && error) {\n const fallbackProps: FallbackProps = {\n error,\n errorInfo,\n resetErrorBoundary: this.reset,\n };\n\n // Render function fallback\n if (typeof fallback === 'function') {\n return fallback(fallbackProps);\n }\n\n // Static fallback\n if (fallback) {\n return fallback;\n }\n\n // Default fallback\n return <DefaultFallback {...fallbackProps} />;\n }\n\n return children;\n }\n}\n\n/**\n * Higher-order component to wrap a component with ErrorBoundary\n *\n * @example\n * ```tsx\n * const SafeComponent = withErrorBoundary(MyComponent, {\n * fallback: <ErrorFallback />,\n * onError: (error) => console.error(error),\n * });\n * ```\n */\nexport function withErrorBoundary<P extends object>(\n Component: ComponentType<P>,\n options: WithErrorBoundaryOptions = {}\n): ComponentType<P> {\n const { fallback, onError, capture = true, tags = {}, context = {} } = options;\n\n const Wrapped: React.FC<P> = (props) => (\n <ErrorBoundary\n fallback={fallback}\n onError={onError}\n capture={capture}\n tags={tags}\n context={context}\n >\n <Component {...props} />\n </ErrorBoundary>\n );\n\n // Preserve display name for debugging\n const displayName = Component.displayName || Component.name || 'Component';\n Wrapped.displayName = `withErrorBoundary(${displayName})`;\n\n return Wrapped;\n}\n\n/**\n * useErrorBoundary hook for functional components\n *\n * Note: This doesn't create an error boundary - those must be class components.\n * Instead, this provides a way to show/trigger the nearest error boundary.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { showBoundary } = useErrorBoundary();\n *\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * showBoundary(error);\n * }\n * };\n * }\n * ```\n */\nexport function useErrorBoundary() {\n const [error, setError] = React.useState<Error | null>(null);\n\n // If there's an error, throw it to be caught by the nearest error boundary\n if (error) {\n throw error;\n }\n\n return {\n /**\n * Trigger the nearest error boundary with the given error\n */\n showBoundary: (err: Error) => setError(err),\n\n /**\n * Reset the error state\n */\n resetBoundary: () => setError(null),\n };\n}\n","/**\n * React Hooks for Error Explorer\n */\n\nimport { useContext, useEffect, useCallback, useRef } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport { ErrorExplorerContext } from './context';\n\n/**\n * Use Error Explorer instance\n *\n * Returns the Error Explorer SDK methods for capturing errors and managing context.\n *\n * @example\n * ```tsx\n * const { captureException, addBreadcrumb, setUser } = useErrorExplorer();\n *\n * try {\n * await riskyOperation();\n * } catch (error) {\n * captureException(error);\n * }\n * ```\n */\nexport function useErrorExplorer() {\n // Try to get from context first (if using provider)\n const contextValue = useContext(ErrorExplorerContext);\n\n // If context is available and initialized, use it\n if (contextValue?.isInitialized) {\n return contextValue;\n }\n\n // Fall back to singleton\n return {\n isInitialized: ErrorExplorer.isInitialized(),\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n };\n}\n\n/**\n * Error handler hook for async operations\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { handleError, wrapAsync } = useErrorHandler();\n *\n * // Option 1: Wrap async function\n * const safeSubmit = wrapAsync(async () => {\n * await api.submit(data);\n * });\n *\n * // Option 2: Manual handling\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * handleError(error, { tags: { operation: 'risky' } });\n * }\n * };\n * }\n * ```\n */\nexport function useErrorHandler(defaultContext?: CaptureContext) {\n const { captureException } = useErrorExplorer();\n\n /**\n * Handle an error with optional context\n */\n const handleError = useCallback(\n (error: unknown, context?: CaptureContext): Error => {\n const err = error instanceof Error ? error : new Error(String(error));\n\n captureException(err, {\n ...defaultContext,\n ...context,\n tags: {\n ...defaultContext?.tags,\n ...context?.tags,\n },\n extra: {\n ...defaultContext?.extra,\n ...context?.extra,\n },\n });\n\n return err;\n },\n [captureException, defaultContext]\n );\n\n /**\n * Wrap an async function with error handling\n */\n const wrapAsync = useCallback(\n <T extends (...args: any[]) => Promise<any>>(\n fn: T,\n context?: CaptureContext\n ): ((...args: Parameters<T>) => Promise<Awaited<ReturnType<T>> | undefined>) => {\n return async (...args: Parameters<T>) => {\n try {\n return await fn(...args);\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n };\n },\n [handleError]\n );\n\n /**\n * Create a try-catch wrapper that captures errors\n */\n const tryCatch = useCallback(\n <T>(fn: () => T, context?: CaptureContext): T | undefined => {\n try {\n return fn();\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n },\n [handleError]\n );\n\n return {\n handleError,\n wrapAsync,\n tryCatch,\n };\n}\n\n/**\n * User context hook\n *\n * Sets the user context and cleans up on unmount.\n *\n * @example\n * ```tsx\n * function App() {\n * const user = useCurrentUser();\n *\n * useUserContext(user ? {\n * id: user.id,\n * email: user.email,\n * name: user.name,\n * } : null);\n *\n * return <MainContent />;\n * }\n * ```\n */\nexport function useUserContext(user: UserContext | null) {\n const { setUser, clearUser } = useErrorExplorer();\n const previousUser = useRef<UserContext | null>(null);\n\n useEffect(() => {\n // Only update if user changed\n if (JSON.stringify(user) !== JSON.stringify(previousUser.current)) {\n if (user) {\n setUser(user);\n } else {\n clearUser();\n }\n previousUser.current = user;\n }\n }, [user, setUser, clearUser]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearUser();\n };\n }, [clearUser]);\n\n return { setUser, clearUser };\n}\n\n/**\n * Action tracker hook for user interactions\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { trackAction, trackInteraction } = useActionTracker();\n *\n * const handleSubmit = () => {\n * trackAction('form_submitted', { formId: 'contact' });\n * // ... actual submit logic\n * };\n *\n * return (\n * <button\n * onClick={() => {\n * trackInteraction('submit-button', 'click');\n * handleSubmit();\n * }}\n * >\n * Submit\n * </button>\n * );\n * }\n * ```\n */\nexport function useActionTracker(componentName?: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n /**\n * Track a user action\n */\n const trackAction = useCallback(\n (action: string, data?: Record<string, unknown>) => {\n addBreadcrumb({\n type: 'user-action',\n category: 'action',\n message: action,\n level: 'info',\n data: {\n component: componentName,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n /**\n * Track a UI interaction\n */\n const trackInteraction = useCallback(\n (\n element: string,\n action: 'click' | 'input' | 'focus' | 'blur' | 'submit',\n data?: Record<string, unknown>\n ) => {\n addBreadcrumb({\n type: 'user-action',\n category: `ui.${action}`,\n message: `${action} on ${element}`,\n level: 'info',\n data: {\n component: componentName,\n element,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n return {\n trackAction,\n trackInteraction,\n };\n}\n\n/**\n * Component lifecycle tracking hook\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * useComponentBreadcrumbs('MyComponent');\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useComponentBreadcrumbs(componentName: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n useEffect(() => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} mounted`,\n level: 'debug',\n });\n\n return () => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} unmounted`,\n level: 'debug',\n });\n };\n }, [componentName, addBreadcrumb]);\n}\n","/**\n * @error-explorer/react\n * Error Explorer SDK for React - Automatic error tracking with React integration\n */\n\n// Import for default export\nimport { ErrorExplorerProvider as Provider } from './context';\n\n// Provider and initialization\nexport { ErrorExplorerProvider, ErrorExplorerContext, initErrorExplorer } from './context';\n\n// Error Boundary\nexport { ErrorBoundary, withErrorBoundary, useErrorBoundary } from './ErrorBoundary';\n\n// Hooks\nexport {\n useErrorExplorer,\n useErrorHandler,\n useUserContext,\n useActionTracker,\n useComponentBreadcrumbs,\n} from './hooks';\n\n// Types\nexport type {\n ReactErrorExplorerOptions,\n ReactComponentContext,\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n ErrorExplorerProviderProps,\n ErrorExplorerContextValue,\n WithErrorBoundaryOptions,\n InitOptions,\n UserContext,\n Breadcrumb,\n CaptureContext,\n} from './types';\n\n// Re-export ErrorExplorer for direct access\nexport { ErrorExplorer } from '@error-explorer/browser';\n\n// Default export is the provider for convenience\nexport default Provider;\n"],"mappings":"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","names":["React","ErrorExplorer","jsx","Component","useEffect","ErrorExplorer","ErrorExplorer","useEffect","ErrorExplorer"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.tsx","../src/ErrorBoundary.tsx","../src/hooks.ts","../src/index.ts"],"sourcesContent":["/**\n * React Context Provider for Error Explorer\n */\n\nimport React, { createContext, useEffect, useState, useMemo, type ReactNode } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport type { ReactErrorExplorerOptions, ErrorExplorerContextValue } from './types';\n\n/**\n * React Context for Error Explorer\n */\nexport const ErrorExplorerContext = createContext<ErrorExplorerContextValue | null>(null);\n\n/**\n * Error Explorer Provider Component\n *\n * Initializes the Error Explorer SDK and provides context to child components.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <ErrorExplorerProvider\n * options={{\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * }}\n * >\n * <MainContent />\n * </ErrorExplorerProvider>\n * );\n * }\n * ```\n */\nexport function ErrorExplorerProvider({\n options,\n children,\n}: {\n options: ReactErrorExplorerOptions;\n children: ReactNode;\n}) {\n const [isInitialized, setIsInitialized] = useState(false);\n\n // Initialize on mount\n useEffect(() => {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n setIsInitialized(true);\n } else {\n setIsInitialized(true);\n }\n\n // Cleanup on unmount\n return () => {\n // Don't close on unmount as other components might still need it\n // ErrorExplorer.close();\n };\n }, []); // Only run once on mount\n\n // Create stable context value\n const contextValue = useMemo<ErrorExplorerContextValue>(\n () => ({\n isInitialized,\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n }),\n [isInitialized]\n );\n\n return (\n <ErrorExplorerContext.Provider value={contextValue}>\n {children}\n </ErrorExplorerContext.Provider>\n );\n}\n\n/**\n * Initialize Error Explorer directly (without provider)\n *\n * Use this if you don't need the React Context and just want to initialize\n * the SDK globally.\n *\n * @example\n * ```tsx\n * // In your entry file (main.tsx)\n * import { initErrorExplorer } from '@error-explorer/react';\n *\n * initErrorExplorer({\n * token: 'ee_your_token',\n * project: 'my-react-app',\n * environment: 'production',\n * });\n *\n * ReactDOM.createRoot(root).render(<App />);\n * ```\n */\nexport function initErrorExplorer(options: ReactErrorExplorerOptions): void {\n if (!ErrorExplorer.isInitialized()) {\n ErrorExplorer.init(options);\n }\n}\n","/**\n * ErrorBoundary component for React\n * Catches errors in child components and reports them to Error Explorer\n */\n\nimport React, { Component, type ReactNode, type ComponentType } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type {\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n WithErrorBoundaryOptions,\n} from './types';\n\n/**\n * Default fallback component\n */\nconst DefaultFallback: React.FC<FallbackProps> = ({ error, resetErrorBoundary }) => (\n <div\n role=\"alert\"\n style={{\n padding: '20px',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n backgroundColor: '#f8d7da',\n color: '#721c24',\n }}\n >\n <h2 style={{ margin: '0 0 10px 0' }}>Something went wrong</h2>\n <pre style={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n backgroundColor: 'rgba(0,0,0,0.1)',\n padding: '10px',\n borderRadius: '4px',\n fontSize: '14px',\n }}>\n {error.message}\n </pre>\n <button\n onClick={resetErrorBoundary}\n style={{\n marginTop: '10px',\n padding: '8px 16px',\n backgroundColor: '#721c24',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Try again\n </button>\n </div>\n);\n\n/**\n * ErrorBoundary class component\n *\n * React Error Boundaries must be class components - there's no hook equivalent.\n *\n * @example\n * ```tsx\n * <ErrorBoundary fallback={<ErrorFallback />}>\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n *\n * @example\n * With render prop fallback:\n * ```tsx\n * <ErrorBoundary\n * fallback={({ error, resetErrorBoundary }) => (\n * <div>\n * <p>Error: {error.message}</p>\n * <button onClick={resetErrorBoundary}>Retry</button>\n * </div>\n * )}\n * >\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n static defaultProps = {\n capture: true,\n captureComponentStack: true,\n tags: {},\n context: {},\n };\n\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.setState({ errorInfo });\n\n const {\n capture = true,\n captureComponentStack = true,\n beforeReactCapture,\n tags = {},\n context = {},\n onError,\n } = this.props;\n\n // Call user's error handler\n if (onError) {\n onError(error, errorInfo);\n }\n\n // Check if capture is enabled\n if (!capture) {\n return;\n }\n\n // Call beforeReactCapture hook - if it returns false, skip capturing\n if (beforeReactCapture) {\n const shouldCapture = beforeReactCapture(error, errorInfo);\n if (shouldCapture === false) {\n return;\n }\n }\n\n // Build extra context\n const extra: Record<string, unknown> = { ...context };\n\n // Only include component stack if enabled\n if (captureComponentStack && errorInfo.componentStack) {\n extra.componentStack = errorInfo.componentStack;\n }\n\n // Capture to Error Explorer\n ErrorExplorer.captureException(error, {\n tags: {\n 'react.errorBoundary': 'true',\n ...tags,\n },\n extra,\n });\n }\n\n componentDidUpdate(prevProps: ErrorBoundaryProps): void {\n const { resetKeys } = this.props;\n const { hasError } = this.state;\n\n // Reset if resetKeys changed\n if (hasError && resetKeys && prevProps.resetKeys) {\n const hasResetKeyChanged = resetKeys.some(\n (key, index) => key !== prevProps.resetKeys?.[index]\n );\n\n if (hasResetKeyChanged) {\n this.reset();\n }\n }\n }\n\n reset = (): void => {\n const { onReset } = this.props;\n\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n\n if (onReset) {\n onReset();\n }\n };\n\n render(): ReactNode {\n const { hasError, error, errorInfo } = this.state;\n const { children, fallback } = this.props;\n\n if (hasError && error) {\n const fallbackProps: FallbackProps = {\n error,\n errorInfo,\n resetErrorBoundary: this.reset,\n };\n\n // Render function fallback\n if (typeof fallback === 'function') {\n return fallback(fallbackProps);\n }\n\n // Static fallback\n if (fallback) {\n return fallback;\n }\n\n // Default fallback\n return <DefaultFallback {...fallbackProps} />;\n }\n\n return children;\n }\n}\n\n/**\n * Higher-order component to wrap a component with ErrorBoundary\n *\n * @example\n * ```tsx\n * const SafeComponent = withErrorBoundary(MyComponent, {\n * fallback: <ErrorFallback />,\n * onError: (error) => console.error(error),\n * });\n * ```\n */\nexport function withErrorBoundary<P extends object>(\n Component: ComponentType<P>,\n options: WithErrorBoundaryOptions = {}\n): ComponentType<P> {\n const {\n fallback,\n onError,\n capture = true,\n captureComponentStack = true,\n beforeReactCapture,\n tags = {},\n context = {},\n } = options;\n\n const Wrapped: React.FC<P> = (props) => (\n <ErrorBoundary\n fallback={fallback}\n onError={onError}\n capture={capture}\n captureComponentStack={captureComponentStack}\n beforeReactCapture={beforeReactCapture}\n tags={tags}\n context={context}\n >\n <Component {...props} />\n </ErrorBoundary>\n );\n\n // Preserve display name for debugging\n const displayName = Component.displayName || Component.name || 'Component';\n Wrapped.displayName = `withErrorBoundary(${displayName})`;\n\n return Wrapped;\n}\n\n/**\n * useErrorBoundary hook for functional components\n *\n * Note: This doesn't create an error boundary - those must be class components.\n * Instead, this provides a way to show/trigger the nearest error boundary.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { showBoundary } = useErrorBoundary();\n *\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * showBoundary(error);\n * }\n * };\n * }\n * ```\n */\nexport function useErrorBoundary() {\n const [error, setError] = React.useState<Error | null>(null);\n\n // If there's an error, throw it to be caught by the nearest error boundary\n if (error) {\n throw error;\n }\n\n return {\n /**\n * Trigger the nearest error boundary with the given error\n */\n showBoundary: (err: Error) => setError(err),\n\n /**\n * Reset the error state\n */\n resetBoundary: () => setError(null),\n };\n}\n","/**\n * React Hooks for Error Explorer\n */\n\nimport { useContext, useEffect, useCallback, useRef } from 'react';\nimport { ErrorExplorer } from '@error-explorer/browser';\nimport type { Breadcrumb, CaptureContext, UserContext } from '@error-explorer/browser';\nimport { ErrorExplorerContext } from './context';\n\n/**\n * Use Error Explorer instance\n *\n * Returns the Error Explorer SDK methods for capturing errors and managing context.\n *\n * @example\n * ```tsx\n * const { captureException, addBreadcrumb, setUser } = useErrorExplorer();\n *\n * try {\n * await riskyOperation();\n * } catch (error) {\n * captureException(error);\n * }\n * ```\n */\nexport function useErrorExplorer() {\n // Try to get from context first (if using provider)\n const contextValue = useContext(ErrorExplorerContext);\n\n // If context is available and initialized, use it\n if (contextValue?.isInitialized) {\n return contextValue;\n }\n\n // Fall back to singleton\n return {\n isInitialized: ErrorExplorer.isInitialized(),\n captureException: (error: Error, context?: CaptureContext) =>\n ErrorExplorer.captureException(error, context),\n captureMessage: (message: string, level?: 'debug' | 'info' | 'warning' | 'error' | 'critical') =>\n ErrorExplorer.captureMessage(message, level),\n addBreadcrumb: (breadcrumb: Breadcrumb) => ErrorExplorer.addBreadcrumb(breadcrumb),\n setUser: (user: UserContext) => ErrorExplorer.setUser(user),\n clearUser: () => ErrorExplorer.clearUser(),\n setTag: (key: string, value: string) => ErrorExplorer.setTag(key, value),\n setTags: (tags: Record<string, string>) => ErrorExplorer.setTags(tags),\n setExtra: (extra: Record<string, unknown>) => ErrorExplorer.setExtra(extra),\n setContext: (name: string, context: Record<string, unknown>) =>\n ErrorExplorer.setContext(name, context),\n flush: (timeout?: number) => ErrorExplorer.flush(timeout),\n close: (timeout?: number) => ErrorExplorer.close(timeout),\n };\n}\n\n/**\n * Error handler hook for async operations\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { handleError, wrapAsync } = useErrorHandler();\n *\n * // Option 1: Wrap async function\n * const safeSubmit = wrapAsync(async () => {\n * await api.submit(data);\n * });\n *\n * // Option 2: Manual handling\n * const handleClick = async () => {\n * try {\n * await riskyOperation();\n * } catch (error) {\n * handleError(error, { tags: { operation: 'risky' } });\n * }\n * };\n * }\n * ```\n */\nexport function useErrorHandler(defaultContext?: CaptureContext) {\n const { captureException } = useErrorExplorer();\n\n /**\n * Handle an error with optional context\n */\n const handleError = useCallback(\n (error: unknown, context?: CaptureContext): Error => {\n const err = error instanceof Error ? error : new Error(String(error));\n\n captureException(err, {\n ...defaultContext,\n ...context,\n tags: {\n ...defaultContext?.tags,\n ...context?.tags,\n },\n extra: {\n ...defaultContext?.extra,\n ...context?.extra,\n },\n });\n\n return err;\n },\n [captureException, defaultContext]\n );\n\n /**\n * Wrap an async function with error handling\n */\n const wrapAsync = useCallback(\n <T extends (...args: any[]) => Promise<any>>(\n fn: T,\n context?: CaptureContext\n ): ((...args: Parameters<T>) => Promise<Awaited<ReturnType<T>> | undefined>) => {\n return async (...args: Parameters<T>) => {\n try {\n return await fn(...args);\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n };\n },\n [handleError]\n );\n\n /**\n * Create a try-catch wrapper that captures errors\n */\n const tryCatch = useCallback(\n <T>(fn: () => T, context?: CaptureContext): T | undefined => {\n try {\n return fn();\n } catch (error) {\n handleError(error, context);\n return undefined;\n }\n },\n [handleError]\n );\n\n return {\n handleError,\n wrapAsync,\n tryCatch,\n };\n}\n\n/**\n * User context hook\n *\n * Sets the user context and cleans up on unmount.\n *\n * @example\n * ```tsx\n * function App() {\n * const user = useCurrentUser();\n *\n * useUserContext(user ? {\n * id: user.id,\n * email: user.email,\n * name: user.name,\n * } : null);\n *\n * return <MainContent />;\n * }\n * ```\n */\nexport function useUserContext(user: UserContext | null) {\n const { setUser, clearUser } = useErrorExplorer();\n const previousUser = useRef<UserContext | null>(null);\n\n useEffect(() => {\n // Only update if user changed\n if (JSON.stringify(user) !== JSON.stringify(previousUser.current)) {\n if (user) {\n setUser(user);\n } else {\n clearUser();\n }\n previousUser.current = user;\n }\n }, [user, setUser, clearUser]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearUser();\n };\n }, [clearUser]);\n\n return { setUser, clearUser };\n}\n\n/**\n * Action tracker hook for user interactions\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { trackAction, trackInteraction } = useActionTracker();\n *\n * const handleSubmit = () => {\n * trackAction('form_submitted', { formId: 'contact' });\n * // ... actual submit logic\n * };\n *\n * return (\n * <button\n * onClick={() => {\n * trackInteraction('submit-button', 'click');\n * handleSubmit();\n * }}\n * >\n * Submit\n * </button>\n * );\n * }\n * ```\n */\nexport function useActionTracker(componentName?: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n /**\n * Track a user action\n */\n const trackAction = useCallback(\n (action: string, data?: Record<string, unknown>) => {\n addBreadcrumb({\n type: 'user-action',\n category: 'action',\n message: action,\n level: 'info',\n data: {\n component: componentName,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n /**\n * Track a UI interaction\n */\n const trackInteraction = useCallback(\n (\n element: string,\n action: 'click' | 'input' | 'focus' | 'blur' | 'submit',\n data?: Record<string, unknown>\n ) => {\n addBreadcrumb({\n type: 'user-action',\n category: `ui.${action}`,\n message: `${action} on ${element}`,\n level: 'info',\n data: {\n component: componentName,\n element,\n ...data,\n },\n });\n },\n [addBreadcrumb, componentName]\n );\n\n return {\n trackAction,\n trackInteraction,\n };\n}\n\n/**\n * Component lifecycle tracking hook\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * useComponentBreadcrumbs('MyComponent');\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useComponentBreadcrumbs(componentName: string) {\n const { addBreadcrumb } = useErrorExplorer();\n\n useEffect(() => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} mounted`,\n level: 'debug',\n });\n\n return () => {\n addBreadcrumb({\n type: 'debug',\n category: 'react.lifecycle',\n message: `${componentName} unmounted`,\n level: 'debug',\n });\n };\n }, [componentName, addBreadcrumb]);\n}\n","/**\n * @error-explorer/react\n * Error Explorer SDK for React - Automatic error tracking with React integration\n */\n\n// Import for default export\nimport { ErrorExplorerProvider as Provider } from './context';\n\n// Provider and initialization\nexport { ErrorExplorerProvider, ErrorExplorerContext, initErrorExplorer } from './context';\n\n// Error Boundary\nexport { ErrorBoundary, withErrorBoundary, useErrorBoundary } from './ErrorBoundary';\n\n// Hooks\nexport {\n useErrorExplorer,\n useErrorHandler,\n useUserContext,\n useActionTracker,\n useComponentBreadcrumbs,\n} from './hooks';\n\n// Types\nexport type {\n ReactErrorExplorerOptions,\n ReactComponentContext,\n ErrorBoundaryProps,\n ErrorBoundaryState,\n FallbackProps,\n ErrorExplorerProviderProps,\n ErrorExplorerContextValue,\n WithErrorBoundaryOptions,\n InitOptions,\n UserContext,\n Breadcrumb,\n CaptureContext,\n} from './types';\n\n// Re-export ErrorExplorer for direct access\nexport { ErrorExplorer } from '@error-explorer/browser';\n\n// Default export is the provider for convenience\nexport default Provider;\n"],"mappings":"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","names":["React","ErrorExplorer","jsx","Component","useEffect","ErrorExplorer","ErrorExplorer","useEffect","ErrorExplorer"]}
|