| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import { SupportCategories } from '@supabase/shared-types/out/constants'
- import { ExternalLink } from 'lucide-react'
- import { useRouter } from 'next/router'
- import { Button, cn } from 'ui'
- import { Admonition } from 'ui-patterns'
- import CopyButton from '../CopyButton'
- import { InlineLinkClassName } from '../InlineLink'
- import { SupportLink } from '@/components/interfaces/Support/SupportLink'
- interface ClientSideExceptionHandlerProps {
- message: string
- sentryIssueId: string
- urlMessage: string
- resetErrorBoundary: () => void
- }
- export const ClientSideExceptionHandler = ({
- message,
- sentryIssueId,
- urlMessage,
- resetErrorBoundary,
- }: ClientSideExceptionHandlerProps) => {
- const router = useRouter()
- const isProduction = process.env.NEXT_PUBLIC_ENVIRONMENT !== 'prod'
- const handleClearStorage = () => {
- try {
- localStorage.clear()
- sessionStorage.clear()
- } catch (e) {
- // ignore
- }
- window.location.reload()
- }
- return (
- <>
- <div className="flex flex-col gap-y-1 text-left py-2 w-full">
- <div className="flex items-center justify-between mb-3">
- <p className="text-lg font-bold">Sorry! An unexpected error occurred.</p>
- <CopyButton type="outline" text={message} copyLabel="Copy error" />
- </div>
- <p className="text-sm">
- Application error: a client-side exception has occurred (see browser console for more
- information)
- </p>
- <p className="text-foreground-light text-sm">{message}</p>
- </div>
- <Admonition type="note" showIcon={false} title="We recommend trying the following:">
- <ul className="list-disc mt-1.5 pl-2 list-inside text-sm space-y-1">
- <li>
- <span
- className={cn(InlineLinkClassName, 'cursor-pointer')}
- onClick={() => window.location.reload()}
- >
- Refresh
- </span>{' '}
- the page
- </li>
- <li>
- <span
- className={cn(InlineLinkClassName, 'cursor-pointer')}
- onClick={() => router.push('/logout')}
- >
- Sign out
- </span>{' '}
- and sign back in
- </li>
- <li>
- <span
- className={cn(InlineLinkClassName, 'cursor-pointer')}
- onClick={handleClearStorage}
- >
- Clear your browser storage
- </span>{' '}
- to clean potentially outdated data
- </li>
- <li>Disable browser extensions that might modify page content (e.g. Google Translate)</li>
- <li>If the problem persists, please contact support for assistance</li>
- </ul>
- </Admonition>
- <div className={cn('w-full mx-auto grid gap-2', 'grid-cols-2 sm:w-1/2')}>
- <Button asChild type="default" icon={<ExternalLink />}>
- <SupportLink
- queryParams={{
- category: SupportCategories.DASHBOARD_BUG,
- subject: 'Client side exception occurred on dashboard',
- sid: sentryIssueId,
- error: urlMessage,
- }}
- >
- Contact support
- </SupportLink>
- </Button>
- {/* [Joshen] For local and staging, allow us to escape the error boundary */}
- {/* We could actually investigate how to make this available on prod, but without being able to reliably test this, I'm not keen to do it now */}
- {isProduction ? (
- <Button type="outline" onClick={() => router.reload()}>
- Reload dashboard
- </Button>
- ) : (
- <Button type="outline" onClick={() => resetErrorBoundary()}>
- Return to dashboard
- </Button>
- )}
- </div>
- </>
- )
- }
|