From 926f31b3aadabd22dc5f1693c73567345db6fc56 Mon Sep 17 00:00:00 2001 From: gibbyb Date: Tue, 16 Sep 2025 10:27:32 -0500 Subject: [PATCH] update sentry config to new self hosted sentry --- apps/expo/src/app/_layout.tsx | 2 +- apps/next/.gitignore | 3 + apps/next/env.example | 16 +- apps/next/next.config.js | 12 +- apps/next/package.json | 2 +- apps/next/sentry.server.config.ts | 8 +- .../(sentry)/api/sentry-example-api/route.ts | 14 ++ .../app/(sentry)/sentry-example-page/page.tsx | 209 ++++++++++++++++++ apps/next/src/env.js | 10 +- apps/next/src/instrumentation-client.ts | 8 +- apps/next/src/instrumentation.ts | 11 +- bun.lock | 2 +- 12 files changed, 259 insertions(+), 38 deletions(-) create mode 100644 apps/next/src/app/(sentry)/api/sentry-example-api/route.ts create mode 100644 apps/next/src/app/(sentry)/sentry-example-page/page.tsx diff --git a/apps/expo/src/app/_layout.tsx b/apps/expo/src/app/_layout.tsx index 92f595a..d0d11b1 100644 --- a/apps/expo/src/app/_layout.tsx +++ b/apps/expo/src/app/_layout.tsx @@ -17,7 +17,7 @@ Sentry.init({ profilesSampleRate: 1.0, }); -const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL); +const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!); export const unstable_settings = { anchor: '(tabs)', diff --git a/apps/next/.gitignore b/apps/next/.gitignore index 6053d22..dfe2630 100644 --- a/apps/next/.gitignore +++ b/apps/next/.gitignore @@ -45,3 +45,6 @@ next-env.d.ts # Ignored for the template, you probably want to remove it: package-lock.json + +# Sentry Config File +.env.sentry-build-plugin diff --git a/apps/next/env.example b/apps/next/env.example index 4721e8a..8e852ff 100644 --- a/apps/next/env.example +++ b/apps/next/env.example @@ -1,18 +1,16 @@ +# You can find all default values in the env.js file which makes our values type safe. ### Server Variables ### -# Convex -CONVEX_SELF_HOSTED_URL= -CONVEX_SELF_HOSTED_ADMIN_KEY= -NEXT_PUBLIC_CONVEX_URL= -SETUP_SCRIPT_RAN= +NODE_ENV= # Sentry SENTRY_AUTH_TOKEN= ### Client Variables ### -# Next # Default Values: -NEXT_PUBLIC_SITE_URL='http://localhost:3000' -# Sentry # Default Values +# Next +NEXT_PUBLIC_SITE_URL= +# Convex +NEXT_PUBLIC_CONVEX_URL= +# Sentry NEXT_PUBLIC_SENTRY_DSN= NEXT_PUBLIC_SENTRY_URL= NEXT_PUBLIC_SENTRY_ORG= NEXT_PUBLIC_SENTRY_PROJECT_NAME= - diff --git a/apps/next/next.config.js b/apps/next/next.config.js index 5b3256f..a4c40b7 100644 --- a/apps/next/next.config.js +++ b/apps/next/next.config.js @@ -1,4 +1,4 @@ -import './src/env.js'; +import { env } from './src/env.js'; import { withSentryConfig } from '@sentry/nextjs'; import { withPlausibleProxy } from 'next-plausible'; @@ -32,12 +32,12 @@ const nextConfig = withPlausibleProxy({ const sentryConfig = { // For all available options, see: // https://www.npmjs.com/package/@sentry/webpack-plugin#options - org: 'gib', - project: process.env.NEXT_PUBLIC_SENTRY_PROJECT_NAME, - sentryUrl: process.env.NEXT_PUBLIC_SENTRY_URL, - authToken: process.env.SENTRY_AUTH_TOKEN, + org: env.NEXT_PUBLIC_SENTRY_ORG, + project: env.NEXT_PUBLIC_SENTRY_PROJECT_NAME, + sentryUrl: env.NEXT_PUBLIC_SENTRY_URL, + authToken: env.SENTRY_AUTH_TOKEN, // Only print logs for uploading source maps in CI - silent: !process.env.CI, + silent: !env.CI, // For all available options, see: // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ // Upload a larger set of source maps for prettier stack traces (increases build time) diff --git a/apps/next/package.json b/apps/next/package.json index 255ae55..124dfb0 100644 --- a/apps/next/package.json +++ b/apps/next/package.json @@ -24,7 +24,7 @@ "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", - "@sentry/nextjs": "^10.11.0", + "@sentry/nextjs": "^10", "@t3-oss/env-nextjs": "^0.13.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/apps/next/sentry.server.config.ts b/apps/next/sentry.server.config.ts index f040233..57caf7e 100644 --- a/apps/next/sentry.server.config.ts +++ b/apps/next/sentry.server.config.ts @@ -1,9 +1,9 @@ -// https://docs.sentry.io/platforms/javascript/guides/nextjs/ -import * as Sentry from '@sentry/nextjs'; -import './src/env.js'; +import { env } from './src/env' +import * as Sentry from "@sentry/nextjs"; Sentry.init({ - dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + dsn: env.NEXT_PUBLIC_SENTRY_DSN, tracesSampleRate: 1, + enableLogs: true, debug: false, }); diff --git a/apps/next/src/app/(sentry)/api/sentry-example-api/route.ts b/apps/next/src/app/(sentry)/api/sentry-example-api/route.ts new file mode 100644 index 0000000..a830cfa --- /dev/null +++ b/apps/next/src/app/(sentry)/api/sentry-example-api/route.ts @@ -0,0 +1,14 @@ +import { NextResponse } from "next/server"; + +export const dynamic = "force-dynamic"; +class SentryExampleAPIError extends Error { + constructor(message: string | undefined) { + super(message); + this.name = "SentryExampleAPIError"; + } +} +// A faulty API route to test Sentry's error monitoring +export function GET() { + throw new SentryExampleAPIError("This error is raised on the backend called by the example page."); + return NextResponse.json({ data: "Testing Sentry Error..." }); +} diff --git a/apps/next/src/app/(sentry)/sentry-example-page/page.tsx b/apps/next/src/app/(sentry)/sentry-example-page/page.tsx new file mode 100644 index 0000000..2f6e2d3 --- /dev/null +++ b/apps/next/src/app/(sentry)/sentry-example-page/page.tsx @@ -0,0 +1,209 @@ +"use client"; + +import Head from "next/head"; +import * as Sentry from "@sentry/nextjs"; +import { useState, useEffect } from "react"; + +class SentryExampleFrontendError extends Error { + constructor(message: string | undefined) { + super(message); + this.name = "SentryExampleFrontendError"; + } +} + +export default function Page() { + const [hasSentError, setHasSentError] = useState(false); + const [isConnected, setIsConnected] = useState(true); + + useEffect(() => { + async function checkConnectivity() { + const result = await Sentry.diagnoseSdkConnectivity(); + setIsConnected(result !== 'sentry-unreachable'); + } + checkConnectivity(); + }, []); + + return ( +
+ + sentry-example-page + + + +
+
+ + + +

+ sentry-example-page +

+ +

+ Click the button below, and view the sample error on the Sentry Issues Page. + For more details about setting up Sentry, read our docs. +

+ + + + {hasSentError ? ( +

+ Error sent to Sentry. +

+ ) : !isConnected ? ( +
+

It looks like network requests to Sentry are being blocked, which will prevent errors from being captured. Try disabling your ad-blocker to complete the test.

+
+ ) : ( +
+ )} + +
+ +
+ + +
+ ); +} diff --git a/apps/next/src/env.js b/apps/next/src/env.js index dfeac90..de82473 100644 --- a/apps/next/src/env.js +++ b/apps/next/src/env.js @@ -11,12 +11,14 @@ export const env = createEnv({ CI: z.boolean().default(true), }, client: { - NEXT_PUBLIC_CONVEX_URL: z.url(), NEXT_PUBLIC_SITE_URL: z.url().default('http://localhost:3000'), - NEXT_PUBLIC_SENTRY_DSN: z.url(), - NEXT_PUBLIC_SENTRY_URL: z.url(), + NEXT_PUBLIC_CONVEX_URL: z.url().default('https://api.dev.convex.gbrown.org'), + NEXT_PUBLIC_SENTRY_DSN: z.url().default( + 'https://96df775337cce23d925616dd5aea8857@sentry.gbrown.org/2' + ), + NEXT_PUBLIC_SENTRY_URL: z.url().default('https://sentry.gbrown.org'), NEXT_PUBLIC_SENTRY_ORG: z.string().default('gib'), - NEXT_PUBLIC_SENTRY_PROJECT_NAME: z.string(), + NEXT_PUBLIC_SENTRY_PROJECT_NAME: z.string().default('techtracker-next'), }, runtimeEnv: { NODE_ENV: process.env.NODE_ENV, diff --git a/apps/next/src/instrumentation-client.ts b/apps/next/src/instrumentation-client.ts index 57837ff..6ef7c9e 100644 --- a/apps/next/src/instrumentation-client.ts +++ b/apps/next/src/instrumentation-client.ts @@ -3,14 +3,16 @@ import * as Sentry from '@sentry/nextjs'; Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN!, + integrations: [Sentry.replayIntegration()], // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii sendDefaultPii: true, // https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate - tracesSampleRate: 1.0, - integrations: [Sentry.replayIntegration()], + tracesSampleRate: 1, + enableLogs: true, // https://docs.sentry.io/platforms/javascript/session-replay/configuration/#general-integration-configuration - replaysSessionSampleRate: 0.1, + replaysSessionSampleRate: 0.5, replaysOnErrorSampleRate: 1.0, + debug: false, }); // `captureRouterTransitionStart` is available from SDK version 9.12.0 onwards export const onRouterTransitionStart = Sentry.captureRouterTransitionStart; diff --git a/apps/next/src/instrumentation.ts b/apps/next/src/instrumentation.ts index b77a16f..e1e1f7a 100644 --- a/apps/next/src/instrumentation.ts +++ b/apps/next/src/instrumentation.ts @@ -1,10 +1,3 @@ import * as Sentry from '@sentry/nextjs'; -import type { Instrumentation } from 'next'; - -export const register = async () => { - await import('../sentry.server.config'); -}; - -export const onRequestError: Instrumentation.onRequestError = (...args) => { - Sentry.captureRequestError(...args); -}; +export const register = async () => await import('../sentry.server.config'); +export const onRequestError = Sentry.captureRequestError; diff --git a/bun.lock b/bun.lock index 1366f79..de0940d 100644 --- a/bun.lock +++ b/bun.lock @@ -65,7 +65,7 @@ "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", - "@sentry/nextjs": "^10.11.0", + "@sentry/nextjs": "^10", "@t3-oss/env-nextjs": "^0.13.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1",