Closed
Description
Hi I found a bug in SentryPlugin that makes the stack traces in sentry unreadable when using source maps.
I am using:
"posthog-js": "1.218.2",
"@sentry/react": "^9.1.0",
"@sentry/vite-plugin": "^3.1.0",
node: 22
import * as Sentry from "@sentry/react";
import posthog from "posthog-js";
import React from "react";
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
} from "react-router";
// Using the posthog.sentryIntegrationPlugin makes the stack trace unreadable
Sentry.init({
dsn: ENV.SENTRY_DSN,
integrations: [
Sentry.browserProfilingIntegration(),
Sentry.reactRouterV7BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
posthog.sentryIntegration({
organization: "project",
projectId: 123,
}),
],
});
Stack trace in sentry looks like this. We can only see the minified version:
Work around
I have found a workaround. After inspecting the source code for the sentryPlugin https://github.com/PostHog/posthog-js/blob/main/src/extensions/sentry-integration.ts we can just write it ourself as a custom plugin:
Sentry.init({
dsn: ENV.SENTRY_DSN,
integrations: [
Sentry.browserProfilingIntegration(),
Sentry.reactRouterV7BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
{
name: "posthog-js",
preprocessEvent: (event) => {
if (event.level !== "error") return event;
if (!event.tags) event.tags = {};
const personUrl = posthog.requestRouter.endpointFor(
"ui",
`/project/${posthog.config.token}/person/${posthog.get_distinct_id()}`,
);
event.tags["PostHog Person URL"] = personUrl;
if (posthog.sessionRecordingStarted()) {
event.tags["PostHog Recording URL"] =
posthog.get_session_replay_url({ withTimestamp: true });
}
return event;
},
},
],
});
This only creates a one way binding from Sentry to Posthog and not the other way. But for me this is fine.
Root cause
I think the root cause is that the sentryPlugin is mutating the exceptions of the event from Sentry:
const exceptions: _SentryException[] = event.exception?.values || []
exceptions.forEach((exception) => {
if (exception.stacktrace) {
exception.stacktrace.type = 'raw'
exception.stacktrace.frames.forEach((frame: any) => {
frame.platform = 'web:javascript'
})
}
})
Instead of mutating this i think it should be mapped over and copied to a new variable.
Metadata
Metadata
Assignees
Labels
No labels