| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import * as Sentry from '@sentry/nextjs'
- import { AlertCircle } from 'lucide-react'
- import { ErrorInfo } from 'react'
- import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary'
- import { Alert, AlertDescription, AlertTitle, Button } from 'ui'
- interface ErrorFallbackProps {
- error: Error
- resetErrorBoundary: () => void
- message?: string
- actions?: {
- label: string
- onClick: () => void
- }[]
- sentryContext?: Record<string, any>
- }
- const ErrorFallback = ({
- error: _error,
- resetErrorBoundary,
- message = 'Something went wrong',
- actions = [],
- }: ErrorFallbackProps) => {
- return (
- <div className="p-4 bg-destructive-foreground h-full flex flex-col justify-center items-center">
- <Alert variant="destructive">
- <AlertCircle />
- <AlertTitle>{message}</AlertTitle>
- <AlertDescription>We've been notified and will review and fix this issue.</AlertDescription>
- <div className="mt-4 flex gap-2">
- <Button type="default" onClick={resetErrorBoundary} className="text-sm">
- Try again
- </Button>
- {actions?.map((action, index) => (
- <Button key={index} type="default" onClick={action.onClick} className="text-sm">
- {action.label}
- </Button>
- ))}
- </div>
- </Alert>
- </div>
- )
- }
- interface ErrorBoundaryProps {
- children: React.ReactNode
- message?: string
- actions?: {
- label: string
- onClick: () => void
- }[]
- sentryContext?: Record<string, any>
- onReset?: () => void
- }
- export const ErrorBoundary = ({
- children,
- message,
- actions,
- sentryContext,
- onReset,
- }: ErrorBoundaryProps) => {
- const handleError = (error: Error, info: ErrorInfo) => {
- Sentry.withScope((scope) => {
- scope.setExtra('componentStack', info.componentStack)
- if (sentryContext) {
- Object.entries(sentryContext).forEach(([key, value]) => {
- scope.setExtra(key, value)
- })
- }
- Sentry.captureException(error)
- })
- }
- const handleReset = () => {
- onReset?.()
- }
- return (
- <ReactErrorBoundary
- fallbackRender={({ error, resetErrorBoundary }) => (
- <ErrorFallback
- error={error}
- resetErrorBoundary={resetErrorBoundary}
- message={message}
- actions={actions}
- />
- )}
- onError={handleError}
- onReset={handleReset}
- >
- {children}
- </ReactErrorBoundary>
- )
- }
|