import * as Sentry from '@sentry/nextjs'; const SENTRY_DSN: string | undefined = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; export enum ClientLogType { UNCAUGHT_ERROR_PAGE = 'UNCAUGHT_ERROR_PAGE', CHECKOUT = 'CHECKOUT' } const ALLOWED_CLIENT_LOG_TYPES: ClientLogType[] = [ ClientLogType.UNCAUGHT_ERROR_PAGE, ClientLogType.CHECKOUT ]; const isNetworkError = (exception: unknown): boolean => { if (!(exception instanceof Error)) return false; const networkErrorPatterns = [ 'networkerror', 'failed to fetch', 'network request failed', 'network error', 'loading chunk', 'chunk load failed' ]; if (exception.name === 'NetworkError') return true; if (exception.name === 'TypeError') { return networkErrorPatterns.some((pattern) => exception.message.toLowerCase().includes(pattern) ); } return networkErrorPatterns.some((pattern) => exception.message.toLowerCase().includes(pattern) ); }; export const initSentry = ( type: 'Server' | 'Client' | 'Edge', options: Sentry.BrowserOptions | Sentry.NodeOptions | Sentry.EdgeOptions = {} ) => { // TODO: Remove Zero Project DSN const baseConfig = { dsn: SENTRY_DSN || options.dsn || 'https://d8558ef8997543deacf376c7d8d7cf4b@o64293.ingest.sentry.io/4504338423742464', initialScope: { tags: { APP_TYPE: 'ProjectZeroNext', TYPE: type, ...((options.initialScope as any)?.tags || {}) } }, tracesSampleRate: 0, integrations: [] }; if (type === 'Server' || type === 'Edge') { Sentry.init(baseConfig); } else if (type === 'Client') { Sentry.init({ ...baseConfig, beforeSend: (event, hint) => { if ( !ALLOWED_CLIENT_LOG_TYPES.includes( event.tags?.LOG_TYPE as ClientLogType ) ) { return null; } if (isNetworkError(hint?.originalException)) { return null; } return event; } }); } };