@@ -10,6 +10,7 @@ import { pipeline } from "stream/promises";
1010
1111import { UserConfig } from "./config.js" ;
1212import { LoggerBase , LogId } from "./logger.js" ;
13+ import { MongoLogId } from "mongodb-log-writer" ;
1314
1415export const jsonExportFormat = z . enum ( [ "relaxed" , "canonical" ] ) ;
1516export type JSONExportFormat = z . infer < typeof jsonExportFormat > ;
@@ -71,7 +72,7 @@ export class SessionExportsManager extends EventEmitter<SessionExportsManagerEve
7172 private exportsDirectoryPath : string ;
7273
7374 constructor (
74- readonly sessionId : string ,
75+ sessionId : string ,
7576 private readonly config : SessionExportsManagerConfig ,
7677 private readonly logger : LoggerBase
7778 ) {
@@ -133,7 +134,7 @@ export class SessionExportsManager extends EventEmitter<SessionExportsManagerEve
133134 } catch ( error ) {
134135 this . logger . error ( {
135136 id : LogId . exportReadError ,
136- context : " Error when reading export" ,
137+ context : ` Error when reading export - ${ exportName } ` ,
137138 message : error instanceof Error ? error . message : String ( error ) ,
138139 } ) ;
139140 if ( ( error as NodeJS . ErrnoException ) . code === "ENOENT" ) {
@@ -184,61 +185,54 @@ export class SessionExportsManager extends EventEmitter<SessionExportsManagerEve
184185 jsonExportFormat : JSONExportFormat ;
185186 inProgressExport : InProgressExport ;
186187 } ) : Promise < void > {
188+ let pipeSuccessful = false ;
187189 try {
188190 await fs . mkdir ( this . exportsDirectoryPath , { recursive : true } ) ;
189- const inputStream = input . stream ( ) ;
190- const ejsonDocStream = this . docToEJSONStream ( this . getEJSONOptionsForFormat ( jsonExportFormat ) ) ;
191191 const outputStream = createWriteStream ( inProgressExport . exportPath ) ;
192192 outputStream . write ( "[" ) ;
193- let pipeSuccessful = false ;
194- try {
195- await pipeline ( [ inputStream , ejsonDocStream , outputStream ] ) ;
196- pipeSuccessful = true ;
197- } catch ( pipelineError ) {
198- // If the pipeline errors out then we might end up with
199- // partial and incorrect export so we remove it entirely.
200- await fs . unlink ( inProgressExport . exportPath ) . catch ( ( error ) => {
201- if ( ( error as NodeJS . ErrnoException ) . code !== "ENOENT" ) {
202- this . logger . error ( {
203- id : LogId . exportCreationCleanupError ,
204- context : "Error when removing partial export" ,
205- message : error instanceof Error ? error . message : String ( error ) ,
206- } ) ;
207- }
208- } ) ;
209- delete this . sessionExports [ inProgressExport . exportName ] ;
210- throw pipelineError ;
211- } finally {
212- if ( pipeSuccessful ) {
213- this . sessionExports [ inProgressExport . exportName ] = {
214- ...inProgressExport ,
215- exportCreatedAt : Date . now ( ) ,
216- exportStatus : "ready" ,
217- } ;
218- this . emit ( "export-available" , inProgressExport . exportURI ) ;
219- }
220- void input . close ( ) ;
221- }
193+ await pipeline ( [
194+ input . stream ( ) ,
195+ this . docToEJSONStream ( this . getEJSONOptionsForFormat ( jsonExportFormat ) ) ,
196+ outputStream ,
197+ ] ) ;
198+ pipeSuccessful = true ;
222199 } catch ( error ) {
223200 this . logger . error ( {
224201 id : LogId . exportCreationError ,
225- context : " Error when generating JSON export" ,
202+ context : ` Error when generating JSON export for ${ inProgressExport . exportName } ` ,
226203 message : error instanceof Error ? error . message : String ( error ) ,
227204 } ) ;
205+
206+ // If the pipeline errors out then we might end up with
207+ // partial and incorrect export so we remove it entirely.
208+ await this . silentlyRemoveExport (
209+ inProgressExport . exportPath ,
210+ LogId . exportCreationCleanupError ,
211+ `Error when removing incomplete export ${ inProgressExport . exportName } `
212+ ) ;
213+ delete this . sessionExports [ inProgressExport . exportName ] ;
214+ } finally {
215+ if ( pipeSuccessful ) {
216+ this . sessionExports [ inProgressExport . exportName ] = {
217+ ...inProgressExport ,
218+ exportCreatedAt : Date . now ( ) ,
219+ exportStatus : "ready" ,
220+ } ;
221+ this . emit ( "export-available" , inProgressExport . exportURI ) ;
222+ }
223+ void input . close ( ) ;
228224 }
229225 }
230226
231227 private getEJSONOptionsForFormat ( format : JSONExportFormat ) : EJSONOptions | undefined {
232- if ( format === "relaxed" ) {
233- return {
234- relaxed : true ,
235- } ;
228+ switch ( format ) {
229+ case "relaxed" :
230+ return { relaxed : true } ;
231+ case "canonical" :
232+ return { relaxed : false } ;
233+ default :
234+ return undefined ;
236235 }
237- return format === "canonical"
238- ? {
239- relaxed : false ,
240- }
241- : undefined ;
242236 }
243237
244238 private docToEJSONStream ( ejsonOptions : EJSONOptions | undefined ) : Transform {
@@ -276,7 +270,11 @@ export class SessionExportsManager extends EventEmitter<SessionExportsManagerEve
276270 for ( const { exportPath, exportCreatedAt, exportURI, exportName } of exportsForCleanup ) {
277271 if ( isExportExpired ( exportCreatedAt , this . config . exportTimeoutMs ) ) {
278272 delete this . sessionExports [ exportName ] ;
279- await this . silentlyRemoveExport ( exportPath ) ;
273+ await this . silentlyRemoveExport (
274+ exportPath ,
275+ LogId . exportCleanupError ,
276+ `Considerable error when removing export ${ exportName } `
277+ ) ;
280278 this . emit ( "export-expired" , exportURI ) ;
281279 }
282280 }
@@ -291,7 +289,7 @@ export class SessionExportsManager extends EventEmitter<SessionExportsManagerEve
291289 }
292290 }
293291
294- private async silentlyRemoveExport ( exportPath : string ) : Promise < void > {
292+ private async silentlyRemoveExport ( exportPath : string , logId : MongoLogId , logContext : string ) : Promise < void > {
295293 try {
296294 await fs . unlink ( exportPath ) ;
297295 } catch ( error ) {
@@ -300,8 +298,8 @@ export class SessionExportsManager extends EventEmitter<SessionExportsManagerEve
300298 // we need to flag.
301299 if ( ( error as NodeJS . ErrnoException ) . code !== "ENOENT" ) {
302300 this . logger . error ( {
303- id : LogId . exportCleanupError ,
304- context : "Considerable error when removing export file" ,
301+ id : logId ,
302+ context : logContext ,
305303 message : error instanceof Error ? error . message : String ( error ) ,
306304 } ) ;
307305 }
0 commit comments