import * as Sentry from "@sentry/browser"; import callsites from "callsites"; const SentryEnvHostnameMap: { [key: string]: string } = { "excalidraw.com": "production", "staging.excalidraw.com": "staging", "vercel.app": "staging", }; const SENTRY_DISABLED = import.meta.env.VITE_APP_DISABLE_SENTRY === "true"; // Disable Sentry locally or inside the Docker to avoid noise/respect privacy const onlineEnv = !SENTRY_DISABLED && Object.keys(SentryEnvHostnameMap).find( (item) => window.location.hostname.indexOf(item) >= 0, ); Sentry.init({ dsn: onlineEnv ? "https://7bfc596a5bf945eda6b660d3015a5460@sentry.io/5179260" : undefined, environment: onlineEnv ? SentryEnvHostnameMap[onlineEnv] : undefined, release: import.meta.env.VITE_APP_GIT_SHA, ignoreErrors: [ "undefined is not an object (evaluating 'window.__pad.performLoop')", // Only happens on Safari, but spams our servers. Doesn't break anything "InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing.", // Not much we can do about the IndexedDB closing error /(Failed to fetch|(fetch|loading) dynamically imported module)/i, // This is happening when a service worker tries to load an old asset /QuotaExceededError: (The quota has been exceeded|.*setItem.*Storage)/i, // localStorage quota exceeded "Internal error opening backing store for indexedDB.open", // Private mode and disabled indexedDB ], integrations: [ Sentry.captureConsoleIntegration({ levels: ["error"], }), ], beforeSend(event) { if (event.request?.url) { event.request.url = event.request.url.replace(/#.*$/, ""); } if (!event.exception) { event.exception = { values: [ { type: "ConsoleError", value: event.message ?? "Unknown error", stacktrace: { frames: callsites() .slice(1) .filter( (frame) => frame.getFileName() && !frame.getFileName()?.includes("@sentry_browser.js"), ) .map((frame) => ({ filename: frame.getFileName() ?? undefined, function: frame.getFunctionName() ?? undefined, in_app: !( frame.getFileName()?.includes("node_modules") ?? false ), lineno: frame.getLineNumber() ?? undefined, colno: frame.getColumnNumber() ?? undefined, })), }, mechanism: { type: "instrument", handled: true, data: { function: "console.error", handler: "Sentry.beforeSend", }, }, }, ], }; } return event; }, });