Closed as not planned
Description
Is there an existing issue for this?
- I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- I have reviewed the documentation https://docs.sentry.io/
- I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/remix
SDK Version
7.93
Framework Version
7.79
Link to Sentry event
https://hello-travel.sentry.io/issues/4949583427/events/236fed44801a4b4f8b4ad78bd27886b2/
SDK Setup
Client side configuration
// file: app/entry.client.tsx
import * as Sentry from "@sentry/remix";
Sentry.init({
dsn: "xxxxxxx",
release: getPublicEnv("SENTRY_RELEASE"),
integrations: [
new Sentry.BrowserTracing({
routingInstrumentation: Sentry.remixRouterInstrumentation(
useEffect,
useLocation,
useMatches,
),
}),
// Replay is only available in the client
new Sentry.Replay(),
],
environment: process.env.NODE_ENV,
debug: false,
enabled: "development" !== process.env.NODE_ENV,
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 1,
// Set `tracePropagationTargets` to control for which URLs distribud tracing should be enabled
tracePropagationTargets: [
"localhost",
/^http:\/\/dev\.socialtrip\.com:3333/,
getPublicEnv("SITE_URL"),
],
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 1,
});
// file: app/root.tsx
import { withSentry } from "@sentry/remix";
function App() {
// ....
}
export default withSentry(App, {
errorBoundaryOptions: {
fallback: ErrorBoundary,
},
});
// file: app/entry.server.tsx
import * as Sentry from "@sentry/remix";
// Init sentry
Sentry.init({
dsn: "xxxxx",
release: getPublicEnv("SENTRY_RELEASE"),
environment: process.env.NODE_ENV,
debug: false,
enabled: "development" !== process.env.NODE_ENV,
denyUrls: [
/\/build\//,
/\/favicons\//,
/\/img\//,
/\/fonts\//,
/\/favicon.ico/,
/\/site\.webmanifest/,
],
integrations: [new Sentry.Integrations.Http({ tracing: true })],
tracesSampleRate: 1,
});
// Remix stuff....
// function we export for Remix so it can handle errors
export function handleError(
error: unknown,
{ request }: DataFunctionArgs,
): void {
if (error instanceof Error) {
Sentry.captureRemixServerException(error, "remix.server", request);
} else {
Sentry.captureException(error);
}
}
Server side (lambda) configuration:
// in our lambda handler file
import * as Sentry from "@sentry/node";
Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE,
environment: process.env.NODE_ENV,
enabled: true,
debug: false,
tracesSampleRate: 1,
});
// function we use to capture errors in try/catch
function captureError(
error: unknown,
event: APIGatewayProxyEventV2,
context: Context,
) {
console.error(error);
Sentry.configureScope((scope) => {
scope.setExtra("awsRequestId", event.requestContext.requestId);
scope.setExtra("awsRequestURL", createURLFromEvent(event));
});
Sentry.captureException(error);
}
// our try/catch block is like:
try {
// lambda/remix stuff...
} catch (error) {
captureError(error, event, context);
writeErrorToStream(streamResponse, 500, "Internal Server Error");
} finally {
await Sentry.flush(2000);
streamResponse.end();
}
Deploy flow
Scripts used in package.json:
"scripts": {
"build": "NODE_ENV=production remix build --sourcemap && tsx bin/build-lambda-server.ts",
"deploy": "tsx bin/deploy.ts",
}
- Build remix bundles:
npm run build
The script bin/build-lambda-server.ts
creates a new build with esbuild (and sourcemap enabled) for our lambda function, something like:
// file: bin/build-lambda-server.ts
const result = await esbuild.build({
entryPoints: [`${paths.serverDir}/server.lambda.prod.ts`],
bundle: true,
minify: true,
sourcemap: true,
metafile: true,
platform: "node",
format: "esm",
target: "esnext",
outfile: `${paths.serverBundle}/index.mjs`,
outExtension: { ".js": ".mjs" },
banner: {
js: 'import { createRequire } from "module";const require = createRequire(import.meta.url);',
},
define: {
__SENTRY_DEBUG__: "false",
__RRWEB_EXCLUDE_IFRAME__: "true",
__RRWEB_EXCLUDE_SHADOW_DOM__: "true",
__SENTRY_EXCLUDE_REPLAY_WORKER__: "true",
"process.env.NODE_ENV": '"production"',
},
logLevel: "info",
});
// file: server/server.lambda.prod.ts
export const handler = createStreamRequestHandler({
build: build as any, // this is the remix server build
mode: process.env.NODE_ENV,
getLoadContext: async (request: Request) => {
// specific stuff
},
});
- Deploy both client bundle & lambda function bundle:
npm run deploy
// file bin/deploy.ts
const remixPublicPath = "/_static/"; // same as in remix.config.js publicPath property
const release = execSync("git rev-parse HEAD")
.toString()
.trim()
.substring(0, 12);
// 1. .... build an archive for the lambda
// 2. Send both client & server bundle sourcemaps to Sentry
// client bundle sourcemap is handled by sentry
execSync(
`npx sentry-upload-sourcemaps --org hello-travel --project remix --release ${release} --urlPrefix "~${remixPublicPath}"`,
{ cwd: paths.appDir },
);
// server bundle sourcemap is sent manually
execSync(
`npx sentry-cli sourcemaps upload --org=hello-travel --project=remix --release=${release} --url-prefix="~/var/task" ./server/build/index.mjs.map`,
{
cwd: paths.appDir,
},
);
// 3. other stuff not relevant to sentry (like updating lambda function code, cleanup, etc...)
Steps to Reproduce
Well, see the detailed code samples
Expected Result
Having traces with sourcemapping for both client and server errors.
Please note that I'm pretty sure I saw it working once for client errors. Didn't do any modification since then though....
Actual Result
Client error event example:
Server (lambda function) error event example:
Metadata
Assignees
Type
Projects
Status
No status
Status
Waiting for: Community
Activity