diff --git a/packages/electron/src/main/BacktraceClient.ts b/packages/electron/src/main/BacktraceClient.ts index 3b74821a..300e6444 100644 --- a/packages/electron/src/main/BacktraceClient.ts +++ b/packages/electron/src/main/BacktraceClient.ts @@ -12,8 +12,10 @@ export class BacktraceClient extends NodeBacktraceClient { constructor(clientSetup: BacktraceNodeClientSetup) { super({ ...clientSetup, - modules: [new BacktraceMainElectronModule()], + modules: [], }); + + this.addModule(new BacktraceMainElectronModule(this.fs)); } public static builder(options: BacktraceSetupConfiguration): BacktraceClientBuilder { diff --git a/packages/electron/src/main/modules/BacktraceMainElectronModule.ts b/packages/electron/src/main/modules/BacktraceMainElectronModule.ts index 7f87950f..582ccbca 100644 --- a/packages/electron/src/main/modules/BacktraceMainElectronModule.ts +++ b/packages/electron/src/main/modules/BacktraceMainElectronModule.ts @@ -1,5 +1,14 @@ -import { FileAttachmentsManager, FileBreadcrumbsStorage, NodeFileSystem } from '@backtrace/node'; -import type { BacktraceDatabase } from '@backtrace/sdk-core'; +import { + AttachmentBacktraceDatabaseRecordFactory, + BacktraceConfiguration, + BacktraceStorageModule, + BacktraceStreamStorage, + FileAttachmentsManager, + FileBreadcrumbsStorage, + NodeFsBacktraceFileAttachmentFactory, +} from '@backtrace/node'; +import { NodeFs } from '@backtrace/node/lib/storage/nodeFs.js'; +import type { BacktraceDatabase, BacktraceStorage, BacktraceSyncStorage } from '@backtrace/sdk-core'; import { BacktraceData, BacktraceModule, @@ -10,6 +19,7 @@ import { SummedEvent, } from '@backtrace/sdk-core'; import { app, crashReporter } from 'electron'; +import nodeFs from 'fs'; import { IpcAttachmentReference } from '../../common/ipc/IpcAttachmentReference.js'; import { IpcEvents } from '../../common/ipc/IpcEvents.js'; import { SyncData } from '../../common/models/SyncData.js'; @@ -18,10 +28,12 @@ import { MainIpcTransportHandler } from '../ipc/MainIpcTransportHandler.js'; import { WindowIpcTransport } from '../ipc/WindowIpcTransport.js'; import { IpcAttachment } from './IpcAttachment.js'; -export class BacktraceMainElectronModule implements BacktraceModule { - private _bindData?: BacktraceModuleBindData; +export class BacktraceMainElectronModule implements BacktraceModule { + private _bindData?: BacktraceModuleBindData; + + constructor(private readonly _fs: NodeFs = nodeFs) {} - public bind(bindData: BacktraceModuleBindData): void { + public bind(bindData: BacktraceModuleBindData): void { const { requestHandler, reportSubmission, client, attributeManager } = bindData; const getSyncData = (): SyncData => ({ @@ -102,7 +114,7 @@ export class BacktraceMainElectronModule implements BacktraceModule { return; } - const { options, attributeManager, sessionFiles, fileSystem, database } = this._bindData; + const { options, attributeManager, sessionFiles, storage, database } = this._bindData; if (options.database?.captureNativeCrashes) { if (options.database.path) { @@ -125,9 +137,9 @@ export class BacktraceMainElectronModule implements BacktraceModule { } }); - if (sessionFiles && database && fileSystem) { + if (sessionFiles && database && storage) { const lockId = sessionFiles.lockPreviousSessions(); - this.sendPreviousCrashAttachments(database, sessionFiles, fileSystem as NodeFileSystem).finally( + this.sendPreviousCrashAttachments(database, sessionFiles, storage as BacktraceStorageModule).finally( () => lockId && sessionFiles.unlockPreviousSessions(lockId), ); } @@ -145,7 +157,7 @@ export class BacktraceMainElectronModule implements BacktraceModule { private async sendPreviousCrashAttachments( database: BacktraceDatabase, session: SessionFiles, - fileSystem: NodeFileSystem, + storage: BacktraceStorage & BacktraceSyncStorage & BacktraceStreamStorage, ) { // Sort crashes and sessions by timestamp descending const crashes = crashReporter.getUploadedReports().sort((a, b) => b.date.getTime() - a.date.getTime()); @@ -169,22 +181,31 @@ export class BacktraceMainElectronModule implements BacktraceModule { const crashLock = session.getFileName(`electron-crash-lock-${rxid}`); // If crash lock exists, do not attempt to add attachments twice - if (await fileSystem.exists(crashLock)) { + if (await storage.has(crashLock)) { continue; } - const fileAttachmentsManager = FileAttachmentsManager.createFromSession(session, fileSystem); + const fileAttachmentsManager = FileAttachmentsManager.createFromSession( + session, + storage, + new NodeFsBacktraceFileAttachmentFactory(this._fs), + ); const sessionAttachments = [ - ...FileBreadcrumbsStorage.getSessionAttachments(session, fileSystem), + ...FileBreadcrumbsStorage.getSessionAttachments( + session, + new NodeFsBacktraceFileAttachmentFactory(this._fs), + ), ...(await fileAttachmentsManager.get()), ]; + const recordFactory = AttachmentBacktraceDatabaseRecordFactory.default(); for (const attachment of sessionAttachments) { - database.addAttachment(rxid, attachment, session.sessionId); + const record = recordFactory.create(rxid, session.sessionId, attachment); + database.addRecord(record); } // Write an empty crash lock, so we know that this crash is already taken care of - await fileSystem.writeFile(crashLock, ''); + await storage.set(crashLock, ''); } catch { // Do nothing, skip the report }