@@ -118,28 +118,44 @@ export class SessionExportsManager {
118118 jsonExportFormat : JSONExportFormat ;
119119 } ) : Promise < void > {
120120 try {
121+ const exportNameWithExtension = this . withExtension ( exportName , "json" ) ;
122+ const inputStream = input . stream ( ) ;
123+ const ejsonDocStream = this . docToEJSONStream ( this . getEJSONOptionsForFormat ( jsonExportFormat ) ) ;
121124 await this . withExportsLock < void > ( async ( exportsDirectoryPath ) => {
122- const exportNameWithExtension = this . withExtension ( exportName , "json" ) ;
123125 const exportFilePath = path . join ( exportsDirectoryPath , exportNameWithExtension ) ;
124126 const outputStream = createWriteStream ( exportFilePath ) ;
125127 outputStream . write ( "[" ) ;
128+ let pipeSuccessful = false ;
126129 try {
127- const inputStream = input . stream ( ) ;
128- const ejsonOptions = this . getEJSONOptionsForFormat ( jsonExportFormat ) ;
129- await pipeline ( [ inputStream , this . docToEJSONStream ( ejsonOptions ) , outputStream ] ) ;
130+ await pipeline ( [ inputStream , ejsonDocStream , outputStream ] ) ;
131+ pipeSuccessful = true ;
132+ } catch ( pipelineError ) {
133+ // If the pipeline errors out then we might end up with
134+ // partial and incorrect export so we remove it entirely.
135+ await fs . unlink ( exportFilePath ) . catch ( ( error ) => {
136+ if ( ( error as NodeJS . ErrnoException ) . code !== "ENOENT" ) {
137+ logger . error (
138+ LogId . exportCreationCleanupError ,
139+ "Error when removing partial export" ,
140+ error instanceof Error ? error . message : String ( error )
141+ ) ;
142+ }
143+ } ) ;
144+ throw pipelineError ;
130145 } finally {
131- outputStream . write ( "]\n" ) ;
132- const resourceURI = this . exportNameToResourceURI ( exportNameWithExtension ) ;
133- this . mutableExports = [
134- ...this . mutableExports ,
135- {
136- createdAt : ( await fs . stat ( exportFilePath ) ) . birthtimeMs ,
137- name : exportNameWithExtension ,
138- uri : resourceURI ,
139- } ,
140- ] ;
141- this . session . emit ( "export-available" , resourceURI ) ;
142146 void input . close ( ) ;
147+ if ( pipeSuccessful ) {
148+ const resourceURI = this . exportNameToResourceURI ( exportNameWithExtension ) ;
149+ this . mutableExports = [
150+ ...this . mutableExports ,
151+ {
152+ createdAt : ( await fs . stat ( exportFilePath ) ) . birthtimeMs ,
153+ name : exportNameWithExtension ,
154+ uri : resourceURI ,
155+ } ,
156+ ] ;
157+ this . session . emit ( "export-available" , resourceURI ) ;
158+ }
143159 }
144160 } ) ;
145161 } catch ( error ) {
0 commit comments