import { logger } from '../logger'; import * as Sentry from '@sentry/node'; export interface ErrorContext { organizationId?: string; userId?: string; jobId?: string; jobName?: string; extra?: Record; } let sentryInitialized = false; export function initSentry() { const dsn = process.env.SENTRY_DSN; if (!dsn) { logger.info('[SENTRY] SENTRY_DSN not set — error reporting via logger only'); return; } Sentry.init({ dsn, environment: process.env.NODE_ENV || 'production', tracesSampleRate: 0.1, }); sentryInitialized = true; logger.info('[SENTRY] Initialized'); } export const reportError = (error: unknown, context: ErrorContext) => { const errorMessage = error instanceof Error ? error.message : String(error); const errorStack = error instanceof Error ? error.stack : undefined; logger.error({ msg: `[ERROR-REPORT] ${context.jobName || 'unknown'}: ${errorMessage}`, context: { ...context, stack: errorStack } }); if (sentryInitialized) { Sentry.withScope(scope => { scope.setTags({ jobName: context.jobName ?? 'unknown', organizationId: context.organizationId ?? 'unknown', }); if (context.extra) scope.setExtras(context.extra); Sentry.captureException(error); }); } }; export const withErrorLogging = async ( task: () => Promise, context: ErrorContext ): Promise => { try { return await task(); } catch (error) { reportError(error, context); throw error; // Rethrow to let BullMQ handle retries } };