Files
prowler/ui/sentry/sentry.server.config.ts
2026-07-20 16:34:24 +02:00

99 lines
2.9 KiB
TypeScript

import * as Sentry from "@sentry/nextjs";
import { readGatedEnv } from "@/lib/integrations";
import { applySentryEventPolicy, SENTRY_EVENT_SOURCE } from "./event-policy";
const sentryDsn = readGatedEnv(
"UI_SENTRY_ENABLED",
"UI_SENTRY_DSN",
"NEXT_PUBLIC_SENTRY_DSN",
);
const sentryEnvironment = readGatedEnv(
"UI_SENTRY_ENABLED",
"UI_SENTRY_ENVIRONMENT",
"NEXT_PUBLIC_SENTRY_ENVIRONMENT",
);
// Only initialize Sentry if DSN is configured
if (sentryDsn) {
// Default to a non-dev environment so an unset UI_SENTRY_ENVIRONMENT never
// runs in dev mode (100% sampling); only an explicit "local" enables it.
// Mirrors the browser SDK (instrumentation-client.ts) so all runtimes resolve
// the env identically.
const environment = sentryEnvironment ?? "production";
const isDevelopment = environment === "local";
/**
* Server-side Sentry configuration
*
* This setup includes:
* - Performance monitoring for server-side operations
* - Error tracking for API routes and server actions
* - beforeSend hook to filter noise and add context
*/
Sentry.init({
// 📍 DSN - Data Source Name (identifies your Sentry project)
dsn: sentryDsn,
// 🌍 Environment configuration
environment,
// 📦 Release tracking
release: process.env.SENTRY_RELEASE,
// 📊 Sample Rates - Performance monitoring
// 100% in dev (test everything), 50% in production (balance visibility with costs)
tracesSampleRate: isDevelopment ? 1.0 : 0.5,
profilesSampleRate: isDevelopment ? 1.0 : 0.5,
// 🔌 Integrations
integrations: [
Sentry.extraErrorDataIntegration({
depth: 5, // Include up to 5 levels of nested objects
}),
],
// 🎣 Filter expected framework control-flow - Don't send noise to Sentry.
// HTTP status-based suppression belongs in applySentryEventPolicy, where
// structured event context prevents broad numeric matches from hiding crashes.
ignoreErrors: [
// NextAuth redirect errors - Expected behavior
"NEXT_REDIRECT",
"NEXT_NOT_FOUND",
],
beforeSend(event, hint) {
// Add server context and tag errors appropriately
if (event.exception) {
const error = hint.originalException;
// Tag API errors for better filtering in Sentry dashboard
if (
error &&
typeof error === "object" &&
"message" in error &&
typeof error.message === "string"
) {
if (error.message.includes("Server error")) {
event.tags = {
...event.tags,
error_type: "server_error",
severity: "high",
};
} else if (error.message.includes("Request failed")) {
event.tags = {
...event.tags,
error_type: "api_error",
};
}
}
}
return applySentryEventPolicy(event, hint, {
source: SENTRY_EVENT_SOURCE.SERVER,
});
},
});
}