From def11994800a3534e2d69686a7c53bb624b83ad6 Mon Sep 17 00:00:00 2001 From: Abou Kone Date: Sun, 21 Jun 2026 22:30:59 -0400 Subject: [PATCH] fix(web): restore Sentry error reporting Exclude the Sentry tunnel from the auth proxy, capture App Router root errors, upload source maps with the configured token, and use privacy-safe production sampling. Co-Authored-By: Claude --- apps/web/instrumentation-client.js | 16 ++++--------- apps/web/next.config.ts | 6 +---- apps/web/sentry.edge.config.js | 10 ++++---- apps/web/sentry.server.config.js | 10 ++++---- apps/web/src/app/global-error.tsx | 23 +++++++++++++++++++ .../src/lib/__tests__/sentry-config.test.ts | 11 +++++++++ apps/web/src/proxy.ts | 2 +- 7 files changed, 49 insertions(+), 29 deletions(-) create mode 100644 apps/web/src/app/global-error.tsx create mode 100644 apps/web/src/lib/__tests__/sentry-config.test.ts diff --git a/apps/web/instrumentation-client.js b/apps/web/instrumentation-client.js index 7c963c1..b0dee87 100644 --- a/apps/web/instrumentation-client.js +++ b/apps/web/instrumentation-client.js @@ -7,25 +7,19 @@ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: "https://0ddc11d7b3f42d5ca32ecf0b74ff61ef@o4510870266118144.ingest.us.sentry.io/4510870274899968", - // Add optional integrations for additional features integrations: [Sentry.replayIntegration()], - // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. - tracesSampleRate: 1, - // Enable logs to be sent to Sentry + environment: process.env.NODE_ENV, + + tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1, + enableLogs: true, - // Define how likely Replay events are sampled. - // This sets the sample rate to be 10%. You may want this to be 100% while - // in development and sample at a lower rate in production replaysSessionSampleRate: 0.1, - // Define how likely Replay events are sampled when an error occurs. replaysOnErrorSampleRate: 1.0, - // Enable sending user PII (Personally Identifiable Information) - // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii - sendDefaultPii: true, + sendDefaultPii: false, }); export const onRouterTransitionStart = Sentry.captureRouterTransitionStart; diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index 5d59df1..035b8ee 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -36,17 +36,13 @@ const nextConfig: NextConfig = { }; export default withSentryConfig(nextConfig, { - // For all available options, see: - // https://www.npmjs.com/package/@sentry/webpack-plugin#options org: "100kode", project: "vibe-coding-profiler", + authToken: process.env.SENTRY_AUTH_TOKEN, - // Only print logs for uploading source maps in CI silent: !process.env.CI, - // Upload a larger set of source maps for prettier stack traces (increases build time) widenClientFileUpload: true, - // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. tunnelRoute: "/monitoring", }); diff --git a/apps/web/sentry.edge.config.js b/apps/web/sentry.edge.config.js index 4664099..61c015c 100644 --- a/apps/web/sentry.edge.config.js +++ b/apps/web/sentry.edge.config.js @@ -8,13 +8,11 @@ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: "https://0ddc11d7b3f42d5ca32ecf0b74ff61ef@o4510870266118144.ingest.us.sentry.io/4510870274899968", - // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. - tracesSampleRate: 1, + environment: process.env.VERCEL_ENV ?? process.env.NODE_ENV, + + tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1, - // Enable logs to be sent to Sentry enableLogs: true, - // Enable sending user PII (Personally Identifiable Information) - // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii - sendDefaultPii: true, + sendDefaultPii: false, }); diff --git a/apps/web/sentry.server.config.js b/apps/web/sentry.server.config.js index ec593ef..a99d991 100644 --- a/apps/web/sentry.server.config.js +++ b/apps/web/sentry.server.config.js @@ -7,13 +7,11 @@ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: "https://0ddc11d7b3f42d5ca32ecf0b74ff61ef@o4510870266118144.ingest.us.sentry.io/4510870274899968", - // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. - tracesSampleRate: 1, + environment: process.env.VERCEL_ENV ?? process.env.NODE_ENV, + + tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1, - // Enable logs to be sent to Sentry enableLogs: true, - // Enable sending user PII (Personally Identifiable Information) - // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii - sendDefaultPii: true, + sendDefaultPii: false, }); diff --git a/apps/web/src/app/global-error.tsx b/apps/web/src/app/global-error.tsx new file mode 100644 index 0000000..68e60d9 --- /dev/null +++ b/apps/web/src/app/global-error.tsx @@ -0,0 +1,23 @@ +"use client"; + +import * as Sentry from "@sentry/nextjs"; +import NextError from "next/error"; +import { useEffect } from "react"; + +export default function GlobalError({ + error, +}: { + error: Error & { digest?: string }; +}) { + useEffect(() => { + Sentry.captureException(error); + }, [error]); + + return ( + + + + + + ); +} diff --git a/apps/web/src/lib/__tests__/sentry-config.test.ts b/apps/web/src/lib/__tests__/sentry-config.test.ts new file mode 100644 index 0000000..92a3695 --- /dev/null +++ b/apps/web/src/lib/__tests__/sentry-config.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from "vitest"; + +import { config } from "@/proxy"; + +describe("Sentry routing", () => { + it("excludes the Sentry tunnel from the auth proxy", () => { + expect(config.matcher).toEqual([ + "/((?!monitoring|_next/static|_next/image|favicon.ico).*)", + ]); + }); +}); diff --git a/apps/web/src/proxy.ts b/apps/web/src/proxy.ts index e8d6fa7..66bf47c 100644 --- a/apps/web/src/proxy.ts +++ b/apps/web/src/proxy.ts @@ -74,5 +74,5 @@ export async function proxy(request: NextRequest) { } export const config = { - matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], + matcher: ["/((?!monitoring|_next/static|_next/image|favicon.ico).*)"], };