diff --git a/src/main.ts b/src/main.ts index eb307bc4..234490ec 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,6 @@ import { IPC_CHANNELS, DEFAULT_SERVER_ARGS, ProgressStatus, SENTRY_URL_ENDPOINT } from './constants'; import { app, dialog, ipcMain } from 'electron'; import log from 'electron-log/main'; -import * as Sentry from '@sentry/electron/main'; import { findAvailablePort } from './utils'; import dotenv from 'dotenv'; import { AppWindow } from './main-process/appWindow'; @@ -9,6 +8,7 @@ import { PathHandlers } from './handlers/pathHandlers'; import { AppInfoHandlers } from './handlers/appInfoHandlers'; import { ComfyDesktopApp } from './main-process/comfyDesktopApp'; import { LevelOption } from 'electron-log'; +import SentryLogging from './services/sentry'; dotenv.config(); log.initialize(); @@ -28,33 +28,8 @@ app.on('window-all-closed', () => { /** * Sentry needs to be initialized at the top level. - * The `alwaysSendCrashReports` variable is used to determine if crash reports should be sent. */ -let alwaysSendCrashReports = false; -Sentry.init({ - dsn: SENTRY_URL_ENDPOINT, - autoSessionTracking: false, - enabled: process.env.SENTRY_ENABLED === 'true' || app.isPackaged, - beforeSend: async (event, hint) => { - if (event.extra?.comfyUIExecutionError || alwaysSendCrashReports) { - return event; - } - - const { response } = await dialog.showMessageBox({ - title: 'Send Crash Statistics', - message: `Would you like to send crash statistics to the team?`, - buttons: ['Always send crash reports', 'Do not send crash report'], - }); - - return response === 0 ? event : null; - }, - integrations: [ - Sentry.childProcessIntegration({ - breadcrumbs: ['abnormal-exit', 'killed', 'crashed', 'launch-failed', 'oom', 'integrity-failure'], - events: ['abnormal-exit', 'killed', 'crashed', 'launch-failed', 'oom', 'integrity-failure'], - }), - ], -}); +SentryLogging.init(); const gotTheLock = app.requestSingleInstanceLock(); @@ -83,7 +58,7 @@ if (!gotTheLock) { try { const comfyDesktopApp = await ComfyDesktopApp.create(appWindow); await comfyDesktopApp.initialize(); - alwaysSendCrashReports = comfyDesktopApp.comfySettings.get('Comfy-Desktop.SendStatistics'); + SentryLogging.comfyDesktopApp = comfyDesktopApp; const useExternalServer = process.env.USE_EXTERNAL_SERVER === 'true'; const host = process.env.COMFY_HOST || DEFAULT_SERVER_ARGS.host; diff --git a/src/services/sentry.ts b/src/services/sentry.ts new file mode 100644 index 00000000..9c666e50 --- /dev/null +++ b/src/services/sentry.ts @@ -0,0 +1,67 @@ +import * as Sentry from '@sentry/electron/main'; +import { SENTRY_URL_ENDPOINT } from '../constants'; +import { ComfyDesktopApp } from '../main-process/comfyDesktopApp'; +import { app, dialog } from 'electron'; + +class SentryLogging { + comfyDesktopApp: ComfyDesktopApp | undefined; + + init() { + Sentry.init({ + dsn: SENTRY_URL_ENDPOINT, + autoSessionTracking: false, + enabled: process.env.SENTRY_ENABLED === 'true' || app.isPackaged, + beforeSend: async (event) => { + this.filterEvent(event); + + if ( + event.extra?.comfyUIExecutionError || + this.comfyDesktopApp?.comfySettings.get('Comfy-Desktop.SendStatistics') + ) { + return event; + } + + const { response } = await dialog.showMessageBox({ + title: 'Send Crash Statistics', + message: `Would you like to send crash statistics to the team?`, + buttons: ['Always send crash reports', 'Do not send crash report'], + }); + + return response === 0 ? event : null; + }, + integrations: [ + Sentry.childProcessIntegration({ + breadcrumbs: ['abnormal-exit', 'killed', 'crashed', 'launch-failed', 'oom', 'integrity-failure'], + events: ['abnormal-exit', 'killed', 'crashed', 'launch-failed', 'oom', 'integrity-failure'], + }), + ], + }); + } + + private filterEvent(obj: unknown) { + if (!obj || !this.comfyDesktopApp?.basePath) return obj; + + if (typeof obj === 'string') { + return obj.replaceAll(this.comfyDesktopApp.basePath, '[basePath]'); + } + + try { + if (typeof obj === 'object') { + for (const k in obj) { + try { + const record = obj as Record; + record[k] = this.filterEvent(record[k]); + } catch (error) { + // Failed to read/write key + } + } + } + } catch (error) { + // Failed to enumerate keys + } + + return obj; + } +} + +export default new SentryLogging();