Skip to content

Posthog Sentryplugin makes stack trace not readable in Sentry #1753

Closed
@lasseklovstad

Description

@lasseklovstad

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:

Image

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions