mirror of
https://github.com/goauthentik/authentik.git
synced 2026-08-30 18:51:39 -07:00
web: let the error-reporting setting govern Sentry in production
`init({ enabled: process.env.NODE_ENV !== "production" })` disabled the
SDK in exactly the builds that ship: the container's web stage sets
`NODE_ENV=production` (lifecycle/container/Dockerfile), and the bundler
inlines it. An administrator who turned error reporting on in their
config therefore received nothing, while `browserTracingIntegration` was
registered only in production — the opposite polarity — so development
had the SDK on with no tracing integration behind it.
Consolidates the decision into `sentryEnabled(cfg, debug)`:
- The administrator's `errorReporting.enabled` decides, in every
environment; `CanDebug` still forces it on.
- Development additionally honors `?disable-sentry`, so a noisy local
session can opt out for one load without a rebuild.
- The tracing integration is registered whenever the SDK runs. It has
always been configured with the automatic instrumentation off, since
the router opens the spans itself.
`enabled: true` stays on the `init` call so the decision is readable off
the client, which is how the router outlets gate their spans.
Tidy.
139 lines
3.8 KiB
TypeScript
139 lines
3.8 KiB
TypeScript
import { SentryIgnoredError } from "#common/sentry/error";
|
|
|
|
import { RouteInterfaceName } from "#elements/router/utils";
|
|
|
|
import { CapabilitiesEnum, type ErrorReportingConfig, ResponseError } from "@goauthentik/api";
|
|
|
|
import { BrowserOptions, ErrorEvent, EventHint, setTag } from "@sentry/browser";
|
|
|
|
/**
|
|
* Query parameter that turns Sentry off for a single page load.
|
|
*/
|
|
export const DISABLE_SENTRY_PARAM = "disable-sentry";
|
|
|
|
/**
|
|
* The configuration needed to determine whether Sentry should report for this page load.
|
|
*
|
|
* @see {@linkcode isSentryEnabled}
|
|
*/
|
|
export interface SentrySetupOptions {
|
|
/**
|
|
* The deployment's error-reporting configuration.
|
|
*
|
|
* Optional because `Config` types it as required while
|
|
* `ErrorReportingConfigFromJSON` passes a missing value straight through —
|
|
* it is absent whenever the server didn't inject `window.authentik`.
|
|
*/
|
|
errorReporting?: ErrorReportingConfig;
|
|
/**
|
|
* Whether the instance reports the `CanDebug` capability.
|
|
*/
|
|
debug: boolean;
|
|
/**
|
|
* The current query string, i.e. `window.location.search`.
|
|
*/
|
|
search: string;
|
|
/**
|
|
* Whether this is a production build. Defaults to the build-time environment.
|
|
*/
|
|
production?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Whether Sentry should report for this page load.
|
|
*
|
|
* The administrator's `errorReporting.enabled` setting decides, in every
|
|
* environment — a deployment that turns error reporting on expects to receive
|
|
* errors. `CanDebug` enables it on its own, which is what activates Spotlight.
|
|
*
|
|
* Development additionally honors `?disable-sentry`, so a noisy local session
|
|
* can opt out for one load without a rebuild.
|
|
*
|
|
* @category Sentry
|
|
*/
|
|
export function isSentryEnabled({
|
|
errorReporting,
|
|
debug,
|
|
search,
|
|
production = process.env.NODE_ENV === "production",
|
|
}: SentrySetupOptions): boolean {
|
|
if (!errorReporting?.enabled && !debug) return false;
|
|
|
|
if (production) return true;
|
|
|
|
const params = new URLSearchParams(search);
|
|
|
|
return !params.has(DISABLE_SENTRY_PARAM);
|
|
}
|
|
|
|
/**
|
|
* A `beforeSend` callback that ignores certain errors.
|
|
*
|
|
* @category Sentry
|
|
*/
|
|
export function beforeSend(
|
|
event: ErrorEvent,
|
|
hint: EventHint,
|
|
): ErrorEvent | PromiseLike<ErrorEvent | null> | null {
|
|
if (!hint) {
|
|
return event;
|
|
}
|
|
|
|
if (hint.originalException instanceof SentryIgnoredError) {
|
|
return null;
|
|
}
|
|
if (
|
|
hint.originalException instanceof ResponseError ||
|
|
hint.originalException instanceof DOMException
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
return event;
|
|
}
|
|
|
|
/**
|
|
* Include the given capabilities in Sentry events.
|
|
*
|
|
* @category Sentry
|
|
*/
|
|
export function setSentryCapabilities(capabilities: CapabilitiesEnum[]): void {
|
|
setTag("authentik.capabilities", capabilities.join(","));
|
|
}
|
|
|
|
/**
|
|
* Include the given route interface in Sentry events.
|
|
*
|
|
* @category Sentry
|
|
*/
|
|
export function setSentryInterface(interfaceName: RouteInterfaceName) {
|
|
setTag("authentik.component", `web/${interfaceName}`);
|
|
}
|
|
|
|
/**
|
|
* Default Sentry options for the browser.
|
|
*
|
|
* Free of browser globals at module scope, so the policy this module also
|
|
* exports stays importable outside a document.
|
|
*
|
|
* @category Sentry
|
|
*/
|
|
export const DEFAULT_SENTRY_BROWSER_OPTIONS = {
|
|
ignoreErrors: [
|
|
/network/gi,
|
|
/fetch/gi,
|
|
/module/gi,
|
|
// Error on edge on ios,
|
|
// https://stackoverflow.com/questions/69261499/what-is-instantsearchsdkjsbridgeclearhighlight
|
|
/instantSearchSDKJSBridgeClearHighlight/gi,
|
|
// Seems to be an issue in Safari and Firefox
|
|
/MutationObserver.observe/gi,
|
|
/NS_ERROR_FAILURE/gi,
|
|
],
|
|
release:
|
|
process.env.NODE_ENV === "production"
|
|
? `authentik@${import.meta.env.AK_VERSION}`
|
|
: undefined,
|
|
beforeSend,
|
|
} as const satisfies BrowserOptions;
|