From 5f28577df1a0d18aa565b6714ab9b758a77af236 Mon Sep 17 00:00:00 2001 From: Sebastian Alex Date: Fri, 27 Jun 2025 11:28:54 +0200 Subject: [PATCH 1/2] electron: overhaul of database and storage [INT-355] --- .../modules/BacktraceMainElectronModule.ts | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/electron/src/main/modules/BacktraceMainElectronModule.ts b/packages/electron/src/main/modules/BacktraceMainElectronModule.ts index 7f87950f..b7cf43ee 100644 --- a/packages/electron/src/main/modules/BacktraceMainElectronModule.ts +++ b/packages/electron/src/main/modules/BacktraceMainElectronModule.ts @@ -1,5 +1,12 @@ -import { FileAttachmentsManager, FileBreadcrumbsStorage, NodeFileSystem } from '@backtrace/node'; -import type { BacktraceDatabase } from '@backtrace/sdk-core'; +import { + AttachmentBacktraceDatabaseRecordFactory, + BacktraceConfiguration, + BacktraceStorageModule, + BacktraceStreamStorage, + FileAttachmentsManager, + FileBreadcrumbsStorage, +} from '@backtrace/node'; +import type { BacktraceDatabase, BacktraceStorage, BacktraceSyncStorage } from '@backtrace/sdk-core'; import { BacktraceData, BacktraceModule, @@ -18,10 +25,10 @@ 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; - public bind(bindData: BacktraceModuleBindData): void { + public bind(bindData: BacktraceModuleBindData): void { const { requestHandler, reportSubmission, client, attributeManager } = bindData; const getSyncData = (): SyncData => ({ @@ -102,7 +109,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 +132,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 +152,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 +176,24 @@ 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); const sessionAttachments = [ - ...FileBreadcrumbsStorage.getSessionAttachments(session, fileSystem), + ...FileBreadcrumbsStorage.getSessionAttachments(session, storage), ...(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 } From 292c92232b339ba2659bfdeaf9d127938145732c Mon Sep 17 00:00:00 2001 From: Sebastian Alex Date: Fri, 27 Jun 2025 14:43:09 +0200 Subject: [PATCH 2/2] electron: pass NodeFsBacktraceFileAttachmentFactory [INT-355] --- packages/electron/src/main/BacktraceClient.ts | 4 +++- .../main/modules/BacktraceMainElectronModule.ts | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) 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 b7cf43ee..582ccbca 100644 --- a/packages/electron/src/main/modules/BacktraceMainElectronModule.ts +++ b/packages/electron/src/main/modules/BacktraceMainElectronModule.ts @@ -5,7 +5,9 @@ import { 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, @@ -17,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'; @@ -28,6 +31,8 @@ import { IpcAttachment } from './IpcAttachment.js'; export class BacktraceMainElectronModule implements BacktraceModule { private _bindData?: BacktraceModuleBindData; + constructor(private readonly _fs: NodeFs = nodeFs) {} + public bind(bindData: BacktraceModuleBindData): void { const { requestHandler, reportSubmission, client, attributeManager } = bindData; @@ -180,9 +185,16 @@ export class BacktraceMainElectronModule implements BacktraceModule