11import crypto from 'node:crypto'
22import { PassThrough } from 'node:stream'
3- import { styleText } from 'node:util'
43import { contentSecurity } from '@nichtsam/helmet/content'
54import { createReadableStreamFromReadable } from '@react-router/node'
65import * as Sentry from '@sentry/react-router'
76import { isbot } from 'isbot'
87import { renderToPipeableStream } from 'react-dom/server'
9- import {
10- ServerRouter ,
11- type LoaderFunctionArgs ,
12- type ActionFunctionArgs ,
13- type HandleDocumentRequestFunction ,
14- } from 'react-router'
8+ import { type HandleDocumentRequestFunction , ServerRouter } from 'react-router'
159import { getEnv , init } from './utils/env.server.ts'
1610import { getInstanceInfo } from './utils/litefs.server.ts'
1711import { NonceProvider } from './utils/nonce-provider.ts'
@@ -26,7 +20,7 @@ const MODE = process.env.NODE_ENV ?? 'development'
2620
2721type DocRequestArgs = Parameters < HandleDocumentRequestFunction >
2822
29- export default async function handleRequest ( ...args : DocRequestArgs ) {
23+ async function handleRequest ( ...args : DocRequestArgs ) {
3024 const [ request , responseStatusCode , responseHeaders , reactRouterContext ] =
3125 args
3226 const { currentInstance, primaryInstance } = await getInstanceInfo ( )
@@ -74,6 +68,10 @@ export default async function handleRequest(...args: DocRequestArgs) {
7468 'connect-src' : [
7569 MODE === 'development' ? 'ws:' : undefined ,
7670 process . env . SENTRY_DSN ? '*.sentry.io' : undefined ,
71+ // Spotlight (SSE to the sidecar)
72+ MODE === 'development'
73+ ? 'http://localhost:8969'
74+ : undefined ,
7775 "'self'" ,
7876 ] ,
7977 'font-src' : [ "'self'" ] ,
@@ -96,7 +94,8 @@ export default async function handleRequest(...args: DocRequestArgs) {
9694 status : didError ? 500 : responseStatusCode ,
9795 } ) ,
9896 )
99- pipe ( body )
97+ // this enables distributed tracing between client and server!
98+ pipe ( Sentry . getMetaTagTransformer ( body ) )
10099 } ,
101100 onShellError : ( err : unknown ) => {
102101 reject ( err )
@@ -122,21 +121,6 @@ export async function handleDataRequest(response: Response) {
122121 return response
123122}
124123
125- export function handleError (
126- error : unknown ,
127- { request } : LoaderFunctionArgs | ActionFunctionArgs ,
128- ) : void {
129- // Skip capturing if the request is aborted as Remix docs suggest
130- // Ref: https://remix.run/docs/en/main/file-conventions/entry.server#handleerror
131- if ( request . signal . aborted ) {
132- return
133- }
134-
135- if ( error instanceof Error ) {
136- console . error ( styleText ( 'red' , String ( error . stack ) ) )
137- } else {
138- console . error ( error )
139- }
124+ export const handleError = Sentry . createSentryHandleError ( { logErrors : true } )
140125
141- Sentry . captureException ( error )
142- }
126+ export default Sentry . wrapSentryHandleRequest ( handleRequest )
0 commit comments