Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
1 line
12 KiB
Plaintext
1 line
12 KiB
Plaintext
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions } from '@sentry/browser';\nimport { getClient, showReportDialog, withScope } from '@sentry/browser';\nimport type { Scope } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport * as React from 'react';\nimport { DEBUG_BUILD } from './debug-build';\nimport { captureReactException } from './error';\nimport { hoistNonReactStatics } from './hoist-non-react-statics';\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: unknown;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\ntype OnUnmountType = {\n (error: null, componentStack: null, eventId: null): void;\n (error: unknown, componentStack: string, eventId: string): void;\n};\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n dialogOptions?: ReportDialogOptions | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /**\n * If set to `true` or `false`, the error `handled` property will be set to the given value.\n * If unset, the default behaviour is to rely on the presence of the `fallback` prop to determine\n * if the error was handled or not.\n */\n handled?: boolean | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /**\n * Called when the error boundary resets due to a reset call from the\n * fallback render props function.\n */\n onReset?: ((error: unknown, componentStack: string, eventId: string) => void) | undefined;\n /**\n * Called on componentWillUnmount() with the error, componentStack, and eventId.\n *\n * If the error boundary never encountered an error, the error\n * componentStack, and eventId will be null.\n */\n onUnmount?: OnUnmountType | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: unknown, componentStack: string) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: unknown;\n eventId: string;\n };\n\nconst INITIAL_STATE: ErrorBoundaryState = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\n/**\n * A ErrorBoundary component that logs errors to Sentry.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n private _cleanupHook?: () => void;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && props.showDialog) {\n this._openFallbackReportDialog = false;\n this._cleanupHook = client.on('afterSendEvent', event => {\n if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: unknown, errorInfo: React.ErrorInfo): void {\n const { componentStack } = errorInfo;\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n if (beforeCapture) {\n beforeCapture(scope, error, componentStack);\n }\n\n const handled = this.props.handled != null ? this.props.handled : !!this.props.fallback;\n const eventId = captureReactException(error, errorInfo, {\n mechanism: { handled, type: 'auto.function.react.error_boundary' },\n });\n\n if (onError) {\n onError(error, componentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n if (this.state === INITIAL_STATE) {\n // If the error boundary never encountered an error, call onUnmount with null values\n onUnmount(null, null, null);\n } else {\n // `componentStack` and `eventId` are guaranteed to be non-null here because `onUnmount` is only called\n // when the error boundary has already encountered an error.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n onUnmount(error, componentStack!, eventId!);\n }\n }\n\n if (this._cleanupHook) {\n this._cleanupHook();\n this._cleanupHook = undefined;\n }\n }\n\n public resetErrorBoundary(): void {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n // `componentStack` and `eventId` are guaranteed to be non-null here because `onReset` is only called\n // when the error boundary has already encountered an error.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n onReset(error, componentStack!, eventId!);\n }\n this.setState(INITIAL_STATE);\n }\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n // `componentStack` is only null in the initial state, when no error has been captured.\n // If an error has been captured, `componentStack` will be a string.\n // We cannot check `state.error` because null can be thrown as an error.\n if (state.componentStack === null) {\n return typeof children === 'function' ? children() : children;\n }\n\n const element =\n typeof fallback === 'function'\n ? React.createElement(fallback, {\n error: state.error,\n componentStack: state.componentStack,\n resetError: () => this.resetErrorBoundary(),\n eventId: state.eventId,\n })\n : fallback;\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && debug.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped = React.memo((props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n )) as unknown as React.FC<P>;\n\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":[],"mappings":"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"} |