-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
How To: Runtime exceptions in RemixJS actions and loaders? #17439
-
How To: Runtime exceptions in RemixJS actions and loaders?
RemixJS
- @remix-run/express 2.17.0
- @remix-run/node" 2.17.0
- @remix-run/react 2.17.0
Sentry
- @sentry/remix 9.46.0
- @sentry/node 9.40.0
I've followed the instructions in the documentation Server-Side Performance Monitoring to use withSentry() to wrap the App component from the root loader.
Scenario: Runtime exception is caught and sent to Sentry dashboard
Expectation
Would like this to work with Sentry.
// 🚫 Does not send to Sentry dashboard export const action = async ({ request }: ActionFunctionArgs) => { throw new Error('SentryExampleBackendError: error is raised on the backend.') return null }
Actual
This also confirms that the Sentry SDK is working.
// ✅ Does send to Sentry dashboard export const action = async ({ request }: ActionFunctionArgs) => { try { throw new Error('SentryExampleBackendError: error is raised on the backend.') } catch (error) { // Manually capture with additional context Sentry.captureException(error, { tags: { section: 'sentry-example', action: 'sentry-example-page', }, extra: { url: url.toString(), method: request.method, timestamp: new Date().toISOString(), }, }) } return null }
app/entry.server.ts
Sentry.init({ dsn: envVars.SENTRY_DSN, tracesSampleRate: 1, environment: envVars.SENTRY_ENV, integrations: [], })
app/root.tsx
import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix' import { RootErrorBoundary } from './components/RootErrorBoundary' const App = () => { return ( <Layout> <Outlet /> </OSHXpressLayout> ) } export function ErrorBoundary() { const { isProductionEnvironment } = useRootLoaderData() const error = useRouteError() as Error | undefined console.error(`[Sentry][ErrorBoundary] ${error?.name} ${error?.message}`) captureRemixErrorBoundaryError(error) return <RootErrorBoundary error={error} /> } // ✅ Added per the documentation export default withSentry(App)
server/index.ts
import { createRequestHandler } from '@remix-run/express' import express from 'express' import { createServer } from 'vite' export async function buildServer({ argv }) { const app = express() const viteServer = await createServer({ server: { middlewareMode: true, hmr: { port: argv.hmrPort || 443, }, }, }) app.use(viteServer.middlewares) const requestHandler = createRequestHandler({ build: () => viteServer.ssrLoadModule('virtual:remix/server-build'), }) app.all('*', requestHandler) return app }
I've been searching for more information, and have come across various old ways of setting it up that seem to be deprecated:
wrapExpressCreateRequestHandler()is deprecatedautoInstrumentRemixconfig option is deprecated
1. Should this "just work"?
2. Do I need to follow instructions for sentry + expressJS initialization to get support for runtime errors in RemixJS loaders and actions?
3. What am I missing?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment
-
hey, you should not need to do any of that 😅
First of all, no need to install @sentry/node, just @sentry/remix should be enough. This instruments node too under the hood.
If you follow the whole manual setup here:
https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/
And basically remove other things you are doing, then this should just work out of the box. Express is automatically handled through the remix SDK, no need to do any node/express specific stuff - just follow the remix SDK docs :)
Beta Was this translation helpful? Give feedback.