diff --git a/.gitignore b/.gitignore index d909cfed..8b7e3161 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .env*.local output dist +.idea # ts node_modules diff --git a/api/bun.lockb b/api/bun.lockb index 470f8e98..6408494b 100755 Binary files a/api/bun.lockb and b/api/bun.lockb differ diff --git a/api/package.json b/api/package.json index 3a130cad..217c0111 100644 --- a/api/package.json +++ b/api/package.json @@ -7,14 +7,14 @@ "dev": "encore run" }, "devDependencies": { - "@types/node": "^20.5.7", - "typescript": "^5.2.2", - "vitest": "^1.5.0" + "@types/node": "^22.5.4", + "typescript": "^5.6.2", + "vitest": "^2.0.5" }, "dependencies": { - "encore.dev": "^1.35.3" + "encore.dev": "^1.41.0" }, "optionalDependencies": { - "@rollup/rollup-linux-x64-gnu": "^4.13.0" + "@rollup/rollup-linux-x64-gnu": "^4.21.2" } } diff --git a/bun.lockb b/bun.lockb index a9aec668..eac0974b 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/web/.gitignore b/web/.gitignore index 5083fca0..d1dc7456 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -35,4 +35,6 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -.ronin \ No newline at end of file +# Sentry Config File +.env.sentry-build-plugin +.ronin diff --git a/web/app/api/sentry-example-api/route.ts b/web/app/api/sentry-example-api/route.ts new file mode 100644 index 00000000..ca8c0da0 --- /dev/null +++ b/web/app/api/sentry-example-api/route.ts @@ -0,0 +1,9 @@ +import { NextResponse } from "next/server" + +export const dynamic = "force-dynamic" + +// A faulty API route to test Sentry's error monitoring +export function GET() { + throw new Error("Sentry Example API Route Error") + return NextResponse.json({ data: "Testing Sentry Error..." }) +} diff --git a/web/app/global-error.tsx b/web/app/global-error.tsx new file mode 100644 index 00000000..1d4c5617 --- /dev/null +++ b/web/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 ( + + + {/* `NextError` is the default Next.js error page component. Its type + definition requires a `statusCode` prop. However, since the App Router + does not expose status codes for errors, we simply pass 0 to render a + generic error message. */} + + + + ) +} diff --git a/web/app/sentry-example-page/page.tsx b/web/app/sentry-example-page/page.tsx new file mode 100644 index 00000000..f8bb4ebf --- /dev/null +++ b/web/app/sentry-example-page/page.tsx @@ -0,0 +1,82 @@ +"use client" + +import Head from "next/head" +import * as Sentry from "@sentry/nextjs" + +export default function Page() { + return ( +
+ + Sentry Onboarding + + + +
+

+ + + +

+ +

Get started by sending us a sample error:

+ + +

+ Next, look for the error on the{" "} + Issues Page. +

+

+ For more information, see{" "} + + https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +

+
+
+ ) +} diff --git a/web/instrumentation.ts b/web/instrumentation.ts new file mode 100644 index 00000000..7f317a03 --- /dev/null +++ b/web/instrumentation.ts @@ -0,0 +1,5 @@ +export async function register() { + if (process.env.NEXT_RUNTIME === "nodejs") { + await import("./sentry.server.config") + } +} diff --git a/web/next.config.mjs b/web/next.config.mjs index 169ecdc1..afb4643a 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -1,3 +1,4 @@ +import { withSentryConfig } from "@sentry/nextjs" /** @type {import('next').NextConfig} */ const isTauri = process.env.TAURI_ENV_DEBUG !== undefined @@ -41,6 +42,45 @@ const webConfig = { const nextConfig = isTauri ? tauriConfig : webConfig -console.log(`Using ${isTauri ? "Tauri" : "Web"} config`) +// console.log(`Using ${isTauri ? "Tauri" : "Web"} config`) -export default nextConfig +export default withSentryConfig(nextConfig, { + // For all available options, see: + // https://github.com/getsentry/sentry-webpack-plugin#options + + org: "learn-anything", + project: "website", + sentryUrl: "https://sentry.io/", + + // Only print logs for uploading source maps in CI + silent: !process.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) + widenClientFileUpload: true, + + // Automatically annotate React components to show their full name in breadcrumbs and session replay + reactComponentAnnotation: { + enabled: true + }, + + // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. + // This can increase your server load as well as your hosting bill. + // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- + // side errors will fail. + tunnelRoute: "/monitoring", + + // Hides source maps from generated client bundles + hideSourceMaps: true, + + // Automatically tree-shake Sentry logger statements to reduce bundle size + disableLogger: true, + + // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.) + // See the following for more information: + // https://docs.sentry.io/product/crons/ + // https://vercel.com/docs/cron-jobs + automaticVercelMonitors: true +}) diff --git a/web/package.json b/web/package.json index 5ffce2d2..ff84a657 100644 --- a/web/package.json +++ b/web/package.json @@ -95,6 +95,7 @@ "slugify": "^1.6.6", "sonner": "^1.5.0", "streaming-markdown": "^0.0.14", + "@sentry/nextjs": "^8.29.0", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", "vaul": "^0.9.2", diff --git a/web/sentry.client.config.ts b/web/sentry.client.config.ts new file mode 100644 index 00000000..83f4b56c --- /dev/null +++ b/web/sentry.client.config.ts @@ -0,0 +1,26 @@ +// This file configures the initialization of Sentry on the client. +// The config you add here will be used whenever a users loads a page in their browser. +// https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +import * as Sentry from "@sentry/nextjs" + +Sentry.init({ + dsn: "https://643e210c090ea97f641b7f5fb253f16b@o301266.ingest.us.sentry.io/4507927630118912", + + // 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, + + // 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, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: false +}) diff --git a/web/sentry.server.config.ts b/web/sentry.server.config.ts new file mode 100644 index 00000000..61484b30 --- /dev/null +++ b/web/sentry.server.config.ts @@ -0,0 +1,15 @@ +// This file configures the initialization of Sentry on the server. +// The config you add here will be used whenever the server handles a request. +// https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +import * as Sentry from "@sentry/nextjs" + +Sentry.init({ + dsn: "https://643e210c090ea97f641b7f5fb253f16b@o301266.ingest.us.sentry.io/4507927630118912", + + // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. + tracesSampleRate: 1, + + // Setting this option to true will print useful information to the console while you're setting up Sentry. + debug: false +})