Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions app/components/error-boundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
useParams,
useRouteError,
} from '@remix-run/react'
import { captureRemixErrorBoundaryError } from '@sentry/remix'
import * as Sentry from '@sentry/react'
import { useEffect } from 'react'
import { getErrorMessage } from '#app/utils/misc.tsx'

type StatusHandler = (info: {
Expand All @@ -26,7 +27,19 @@ export function GeneralErrorBoundary({
unexpectedErrorHandler?: (error: unknown) => JSX.Element | null
}) {
const error = useRouteError()
captureRemixErrorBoundaryError(error)
useEffect(() => {
if (
typeof document !== 'undefined' &&
!isRouteErrorResponse(error)
) {
Sentry.captureException(error, {
mechanism: {
type: 'react-router',
handled: false,
},
})
}
}, [error])
Comment thread
cursor[bot] marked this conversation as resolved.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant document check inside useEffect hook

Low Severity

The typeof document !== 'undefined' check inside useEffect is redundant. useEffect only executes on the client side where document is always defined, making this guard condition unnecessary.

Fix in Cursor Fix in Web

const params = useParams()

if (typeof document !== 'undefined') {
Expand Down
36 changes: 28 additions & 8 deletions app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type HandleDocumentRequestFunction,
} from '@remix-run/node'
import { RemixServer } from '@remix-run/react'
import * as Sentry from '@sentry/remix'
import * as Sentry from '@sentry/node'
import chalk from 'chalk'
import { isbot } from 'isbot'
import { renderToPipeableStream } from 'react-dom/server'
Expand Down Expand Up @@ -137,16 +137,36 @@ export function handleError(
if (request.signal.aborted) {
return
}
const requestInfo = {
url: request.url,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
}
const captureException = (
exception: unknown,
context?: Parameters<typeof Sentry.captureException>[1],
) => {
Sentry.withScope((scope) => {
scope.addEventProcessor((event) => ({
...event,
request: {
...event.request,
...requestInfo,
},
}))
Sentry.captureException(exception, context)
})
}
if (error instanceof Error) {
console.error(chalk.red(error.stack))
void Sentry.captureRemixServerException(
error,
'remix.server',
request,
true,
)
captureException(error, {
mechanism: {
type: 'react-router',
handled: false,
},
})
Comment thread
cursor[bot] marked this conversation as resolved.
} else {
console.error(chalk.red(error))
Sentry.captureException(error)
captureException(error)
}
}
3 changes: 1 addition & 2 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
ScrollRestoration,
useLoaderData,
} from '@remix-run/react'
import { withSentry } from '@sentry/remix'
import { HoneypotProvider } from 'remix-utils/honeypot/react'
import { GeneralErrorBoundary } from './components/error-boundary.tsx'
import { EpicProgress } from './components/progress-bar.tsx'
Expand Down Expand Up @@ -205,7 +204,7 @@ function AppWithProviders() {
)
}

export default withSentry(AppWithProviders)
export default AppWithProviders

export function ErrorBoundary() {
// the nonce doesn't rely on the loader so we can access that
Expand Down
19 changes: 13 additions & 6 deletions app/utils/monitoring.client.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { useLocation, useMatches } from '@remix-run/react'
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from '@remix-run/react'
import {
browserProfilingIntegration,
init as sentryInit,
browserTracingIntegration,
reactRouterV7BrowserTracingIntegration,
replayIntegration,
browserProfilingIntegration,
} from '@sentry/remix'
} from '@sentry/react'
import { useEffect } from 'react'

export function init() {
Expand All @@ -25,10 +30,12 @@ export function init() {
return event
},
integrations: [
browserTracingIntegration({
reactRouterV7BrowserTracingIntegration({
useEffect,
useLocation,
useMatches,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
Comment thread
cursor[bot] marked this conversation as resolved.
}),
replayIntegration(),
browserProfilingIntegration(),
Expand Down
Loading
Loading