-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update EB to use Sentry, static classNames
- Loading branch information
1 parent
ee4ad59
commit ab4053c
Showing
2 changed files
with
88 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,91 @@ | ||
import React from "react"; | ||
import * as Sentry from "@sentry/react"; | ||
import { logger } from "@utils/logger"; | ||
import { logger } from "@/utils/logger"; | ||
import { getTypeSafeError } from "@/utils/typeSafety/getTypeSafeError"; | ||
import { DefaultErrorFallback } from "./DefaultErrorFallback"; | ||
|
||
/** | ||
* A reusable error-boundary with `Sentry` and logging integrations. | ||
* | ||
* **NOTE:** ErrorBoundary WON'T catch the following: | ||
* - Event-driven errors | ||
* - Uncaught promise rejections | ||
* Default `onError` handler fn for {@link ErrorBoundary} | ||
*/ | ||
export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> { | ||
public override state: ErrorBoundaryState = { | ||
error: null, | ||
hasError: false, | ||
}; | ||
|
||
public static getDerivedStateFromError(error: Error) { | ||
logger.error(error, "ErrorBoundary.getDerivedStateFromError"); | ||
return { hasError: true }; | ||
} | ||
|
||
public override componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { | ||
logger.error( | ||
`${error} | ||
${errorInfo}`, | ||
`ErrorBoundary${this.props?.identifier ? `:${this.props.identifier}` : null}` | ||
); | ||
} | ||
const defaultErrorBoundaryOnErrorHandler: ErrorBoundaryOnErrorHandler = ( | ||
error: Error, | ||
_componentStack: string, | ||
_eventId: string | ||
) => { | ||
logger.error(error, "Sentry.ErrorBoundary"); | ||
}; | ||
|
||
public override render() { | ||
const { showDialog = true, ...props } = this.props; | ||
/** | ||
* Default `fallback` render fn for {@link ErrorBoundary} | ||
*/ | ||
const defaultErrorBoundaryFallback: ErrorBoundaryFallbackFn = ({ error }) => ( | ||
<DefaultErrorFallback errorMessage={getTypeSafeError(error).message} /> | ||
); | ||
|
||
return ( | ||
<Sentry.ErrorBoundary showDialog={showDialog} {...props}> | ||
{this.props.children} | ||
</Sentry.ErrorBoundary> | ||
); | ||
} | ||
/** | ||
;* A reusable [`Sentry ErrorBoundary`][sentry-eb-docs] component. | ||
* | ||
* > **NOTE:** ErrorBoundary components DO NOT catch the following: | ||
* > - Event-driven errors | ||
* > - Uncaught promise rejections | ||
* | ||
* #### [Sentry.ErrorBoundary Options][sentry-eb-opts]: | ||
* | ||
* - `showDialog` - If a [Sentry User Feedback Widget][sentry-feedback-widget] should be rendered | ||
* when the ErrorBoundary catches an error. | ||
* | ||
* - _**Default:**_ `true` | ||
* | ||
* - `dialogOptions` - Options that are passed into the Sentry User Feedback Widget. See all | ||
* possible customization options [here][sentry-feedback-widget-opts]. | ||
* | ||
* - `fallback` - JSX to render when the ErrorBoundary catches an error. Can be JSX or a fn that | ||
* returns JSX. If you provide a fn, Sentry will call it with additional info and helpers. | ||
* | ||
* - _**Default:**_ {@link DefaultErrorFallback|`DefaultErrorFallback`} | ||
* | ||
* - `onError` - A fn that gets called when the ErrorBoundary encounters an error. `onError` is | ||
* useful if you want to propagate the error into a state management library like Redux, or if | ||
* you want to check any side effects that could have occurred due to the error. | ||
* | ||
* - _**Default:**_ {@link logger.error|`logger.error`} | ||
* | ||
* - `onMount` - A fn that gets called in `componentDidMount()`. | ||
* | ||
* - `onUnmount` - A fn that gets called in `componentWillUnmount()`. | ||
* | ||
* - `beforeCapture` - A fn that gets called before an error is sent to Sentry, allowing for extra | ||
* tags or context to be added to the error. | ||
* | ||
* Click [here to view source code][sentry-eb-src] for `Sentry.ErrorBoundary`. | ||
* | ||
* @docs | ||
* - [React docs: Error Boundaries][react-eb-docs] | ||
* - [Sentry.ErrorBoundary][sentry-eb-docs] | ||
* - [Sentry.ErrorBoundary Options][sentry-eb-opts] | ||
* | ||
* [react-eb-docs]: https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary | ||
* [sentry-eb-src]: https://github.com/getsentry/sentry-javascript/blob/develop/packages/react/src/errorboundary.tsx | ||
* [sentry-eb-docs]: https://docs.sentry.io/platforms/javascript/guides/react/features/error-boundary/ | ||
* [sentry-eb-opts]: https://docs.sentry.io/platforms/javascript/guides/react/features/error-boundary/#options | ||
* [sentry-feedback-widget]: https://docs.sentry.io/platforms/javascript/guides/react/enriching-events/user-feedback/ | ||
* [sentry-feedback-widget-opts]: https://docs.sentry.io/platforms/javascript/guides/react/enriching-events/user-feedback/#customizing-the-widget | ||
*/ | ||
export class ErrorBoundary extends Sentry.ErrorBoundary { | ||
public static readonly defaultProps = { | ||
showDialog: true, | ||
onError: defaultErrorBoundaryOnErrorHandler, | ||
fallback: defaultErrorBoundaryFallback, | ||
} satisfies Partial<Sentry.ErrorBoundaryProps>; | ||
} | ||
|
||
export type ErrorBoundaryProps = React.ComponentProps<typeof Sentry.ErrorBoundary> & { | ||
showDialog?: boolean; | ||
identifier?: string; | ||
children?: React.ReactNode; | ||
}; | ||
/** | ||
* `onError` handler fn for {@link ErrorBoundary} | ||
* @note Available `onError` fn args: `error`, `componentStack`, `eventId` | ||
*/ | ||
export type ErrorBoundaryOnErrorHandler = NonNullable<Sentry.ErrorBoundaryProps["onError"]>; | ||
|
||
interface ErrorBoundaryState { | ||
error: Error | string | null; | ||
hasError: boolean; | ||
} | ||
/** | ||
* `fallback` render fn for {@link ErrorBoundary} | ||
* @note Available `fallback` fn args: { `error`, `componentStack`, `eventId`, `resetError` } | ||
*/ | ||
export type ErrorBoundaryFallbackFn = NonNullable<Sentry.ErrorBoundaryProps["fallback"]>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* Class names for `ErrorBoundary` components (src/components/ErrorBoundary/). | ||
*/ | ||
export const errorBoundaryClassNames = { | ||
defaultErrorFallbackRoot: "error-boundary__default-error-fallback-root", | ||
} as const; |