7
7
SessionFiles ,
8
8
VariableDebugIdMapProvider ,
9
9
} from '@backtrace/sdk-core' ;
10
- import path from 'path ' ;
10
+ import nodeFs from 'fs ' ;
11
11
import { BacktraceConfiguration , BacktraceSetupConfiguration } from './BacktraceConfiguration.js' ;
12
12
import { BacktraceNodeRequestHandler } from './BacktraceNodeRequestHandler.js' ;
13
13
import { AGENT } from './agentDefinition.js' ;
@@ -17,39 +17,85 @@ import { FileBreadcrumbsStorage } from './breadcrumbs/FileBreadcrumbsStorage.js'
17
17
import { BacktraceClientBuilder } from './builder/BacktraceClientBuilder.js' ;
18
18
import { BacktraceNodeClientSetup } from './builder/BacktraceClientSetup.js' ;
19
19
import { NodeOptionReader } from './common/NodeOptionReader.js' ;
20
+ import { toArray } from './common/asyncGenerator.js' ;
20
21
import { NodeDiagnosticReportConverter } from './converter/NodeDiagnosticReportConverter.js' ;
21
- import { FsNodeFileSystem } from './storage/FsNodeFileSystem.js' ;
22
- import { NodeFileSystem } from './storage/interfaces/NodeFileSystem.js' ;
22
+ import {
23
+ AttachmentBacktraceDatabaseRecordSender ,
24
+ AttachmentBacktraceDatabaseRecordSerializer ,
25
+ } from './database/AttachmentBacktraceDatabaseRecord.js' ;
26
+ import {
27
+ ReportBacktraceDatabaseRecordWithAttachmentsFactory ,
28
+ ReportBacktraceDatabaseRecordWithAttachmentsSender ,
29
+ ReportBacktraceDatabaseRecordWithAttachmentsSerializer ,
30
+ } from './database/ReportBacktraceDatabaseRecordWithAttachments.js' ;
31
+ import { assertDatabasePath } from './database/utils.js' ;
32
+ import { BacktraceStorageModule } from './storage/BacktraceStorage.js' ;
33
+ import { BacktraceStorageModuleFactory } from './storage/BacktraceStorageModuleFactory.js' ;
34
+ import { NodeFsBacktraceStorageModuleFactory } from './storage/NodeFsBacktraceStorage.js' ;
23
35
24
36
export class BacktraceClient extends BacktraceCoreClient < BacktraceConfiguration > {
25
37
private _listeners : Record < string , NodeJS . UnhandledRejectionListener | NodeJS . UncaughtExceptionListener > = { } ;
26
38
27
- protected get nodeFileSystem ( ) {
28
- return this . fileSystem as NodeFileSystem | undefined ;
39
+ protected readonly storageFactory : BacktraceStorageModuleFactory ;
40
+ protected readonly fs : typeof nodeFs ;
41
+
42
+ protected get databaseNodeFsStorage ( ) {
43
+ return this . databaseStorage as BacktraceStorageModule | undefined ;
29
44
}
30
45
31
46
constructor ( clientSetup : BacktraceNodeClientSetup ) {
32
- const fileSystem = clientSetup . fileSystem ?? new FsNodeFileSystem ( ) ;
47
+ const storageFactory = clientSetup . storageFactory ?? new NodeFsBacktraceStorageModuleFactory ( ) ;
48
+ const fs = clientSetup . fs ?? nodeFs ;
49
+ const storage =
50
+ clientSetup . database ?. storage ??
51
+ ( clientSetup . options . database ?. enable
52
+ ? storageFactory . create ( {
53
+ path : assertDatabasePath ( clientSetup . options . database . path ) ,
54
+ createDirectory : clientSetup . options . database . createDatabaseDirectory ,
55
+ fs,
56
+ } )
57
+ : undefined ) ;
58
+
33
59
super ( {
34
60
sdkOptions : AGENT ,
35
61
requestHandler : new BacktraceNodeRequestHandler ( clientSetup . options ) ,
36
62
debugIdMapProvider : new VariableDebugIdMapProvider ( global as DebugIdContainer ) ,
63
+ database :
64
+ clientSetup . options . database ?. enable && storage
65
+ ? {
66
+ storage,
67
+ reportRecordFactory : ReportBacktraceDatabaseRecordWithAttachmentsFactory . default ( ) ,
68
+ ...clientSetup . database ,
69
+ recordSenders : ( submission ) => ( {
70
+ report : new ReportBacktraceDatabaseRecordWithAttachmentsSender ( submission ) ,
71
+ attachment : new AttachmentBacktraceDatabaseRecordSender ( submission ) ,
72
+ ...clientSetup . database ?. recordSenders ?.( submission ) ,
73
+ } ) ,
74
+ recordSerializers : {
75
+ report : new ReportBacktraceDatabaseRecordWithAttachmentsSerializer ( storage ) ,
76
+ attachment : new AttachmentBacktraceDatabaseRecordSerializer ( fs ) ,
77
+ ...clientSetup . database ?. recordSerializers ,
78
+ } ,
79
+ }
80
+ : undefined ,
37
81
...clientSetup ,
38
- fileSystem,
39
82
options : {
40
83
...clientSetup . options ,
41
84
attachments : clientSetup . options . attachments ?. map ( transformAttachment ) ,
42
85
} ,
43
86
} ) ;
44
87
88
+ this . storageFactory = storageFactory ;
89
+ this . fs = fs ;
90
+
45
91
const breadcrumbsManager = this . modules . get ( BreadcrumbsManager ) ;
46
- if ( breadcrumbsManager && this . sessionFiles ) {
47
- breadcrumbsManager . setStorage ( FileBreadcrumbsStorage . factory ( this . sessionFiles , fileSystem ) ) ;
92
+ if ( breadcrumbsManager && this . sessionFiles && storage ) {
93
+ breadcrumbsManager . setStorage ( FileBreadcrumbsStorage . factory ( this . sessionFiles , storage ) ) ;
48
94
}
49
95
50
- if ( this . sessionFiles && clientSetup . options . database ?. captureNativeCrashes ) {
51
- this . addModule ( FileAttributeManager , FileAttributeManager . create ( fileSystem ) ) ;
52
- this . addModule ( FileAttachmentsManager , FileAttachmentsManager . create ( fileSystem ) ) ;
96
+ if ( this . sessionFiles && storage && clientSetup . options . database ?. captureNativeCrashes ) {
97
+ this . addModule ( FileAttributeManager , FileAttributeManager . create ( storage ) ) ;
98
+ this . addModule ( FileAttachmentsManager , FileAttachmentsManager . create ( storage ) ) ;
53
99
}
54
100
}
55
101
@@ -58,6 +104,7 @@ export class BacktraceClient extends BacktraceCoreClient<BacktraceConfiguration>
58
104
59
105
try {
60
106
super . initialize ( ) ;
107
+
61
108
this . captureUnhandledErrors (
62
109
this . options . captureUnhandledErrors ,
63
110
this . options . captureUnhandledPromiseRejections ,
@@ -242,18 +289,19 @@ export class BacktraceClient extends BacktraceCoreClient<BacktraceConfiguration>
242
289
}
243
290
244
291
private async loadNodeCrashes ( ) {
245
- if ( ! this . database || ! this . nodeFileSystem || ! this . options . database ?. captureNativeCrashes ) {
292
+ if ( ! this . database || ! this . options . database ?. captureNativeCrashes ) {
246
293
return ;
247
294
}
248
295
249
296
const reportName = process . report ?. filename ;
250
- const databasePath = process . report ?. directory
251
- ? process . report . directory
252
- : ( this . options . database ?. path ?? process . cwd ( ) ) ;
297
+ const storage = this . storageFactory . create ( {
298
+ path : process . report ?. directory ? process . report . directory : ( this . options . database ?. path ?? process . cwd ( ) ) ,
299
+ fs : this . fs ,
300
+ } ) ;
253
301
254
302
let databaseFiles : string [ ] ;
255
303
try {
256
- databaseFiles = await this . nodeFileSystem . readDir ( databasePath ) ;
304
+ databaseFiles = await toArray ( storage . keys ( ) ) ;
257
305
} catch {
258
306
return ;
259
307
}
@@ -271,11 +319,14 @@ export class BacktraceClient extends BacktraceCoreClient<BacktraceConfiguration>
271
319
272
320
const reports : [ path : string , report : BacktraceReport , sessionFiles ?: SessionFiles ] [ ] = [ ] ;
273
321
for ( const recordName of recordNames ) {
274
- const recordPath = path . join ( databasePath , recordName ) ;
275
322
try {
276
- const recordJson = await this . nodeFileSystem . readFile ( recordPath ) ;
323
+ const recordJson = await storage . get ( recordName ) ;
324
+ if ( ! recordJson ) {
325
+ continue ;
326
+ }
327
+
277
328
const report = converter . convert ( JSON . parse ( recordJson ) ) ;
278
- reports . push ( [ recordPath , report ] ) ;
329
+ reports . push ( [ recordName , report ] ) ;
279
330
} catch {
280
331
// Do nothing, skip the report
281
332
}
@@ -292,17 +343,15 @@ export class BacktraceClient extends BacktraceCoreClient<BacktraceConfiguration>
292
343
currentSession = currentSession ?. getPreviousSession ( ) ;
293
344
}
294
345
295
- for ( const [ recordPath , report , session ] of reports ) {
346
+ for ( const [ recordName , report , session ] of reports ) {
296
347
try {
297
348
if ( session ) {
298
- report . attachments . push (
299
- ...FileBreadcrumbsStorage . getSessionAttachments ( session , this . nodeFileSystem ) ,
300
- ) ;
349
+ report . attachments . push ( ...FileBreadcrumbsStorage . getSessionAttachments ( session , storage ) ) ;
301
350
302
- const fileAttributes = FileAttributeManager . createFromSession ( session , this . nodeFileSystem ) ;
351
+ const fileAttributes = FileAttributeManager . createFromSession ( session , storage ) ;
303
352
Object . assign ( report . attributes , await fileAttributes . get ( ) ) ;
304
353
305
- const fileAttachments = FileAttachmentsManager . createFromSession ( session , this . nodeFileSystem ) ;
354
+ const fileAttachments = FileAttachmentsManager . createFromSession ( session , storage ) ;
306
355
report . attachments . push ( ...( await fileAttachments . get ( ) ) ) ;
307
356
308
357
report . attributes [ 'application.session' ] = session . sessionId ;
@@ -318,7 +367,7 @@ export class BacktraceClient extends BacktraceCoreClient<BacktraceConfiguration>
318
367
// Do nothing, skip the report
319
368
} finally {
320
369
try {
321
- await this . nodeFileSystem . unlink ( recordPath ) ;
370
+ await storage . remove ( recordName ) ;
322
371
} catch {
323
372
// Do nothing
324
373
}
0 commit comments