@@ -118,28 +118,44 @@ export class SessionExportsManager {
118
118
jsonExportFormat : JSONExportFormat ;
119
119
} ) : Promise < void > {
120
120
try {
121
+ const exportNameWithExtension = this . withExtension ( exportName , "json" ) ;
122
+ const inputStream = input . stream ( ) ;
123
+ const ejsonDocStream = this . docToEJSONStream ( this . getEJSONOptionsForFormat ( jsonExportFormat ) ) ;
121
124
await this . withExportsLock < void > ( async ( exportsDirectoryPath ) => {
122
- const exportNameWithExtension = this . withExtension ( exportName , "json" ) ;
123
125
const exportFilePath = path . join ( exportsDirectoryPath , exportNameWithExtension ) ;
124
126
const outputStream = createWriteStream ( exportFilePath ) ;
125
127
outputStream . write ( "[" ) ;
128
+ let pipeSuccessful = false ;
126
129
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 ;
130
145
} 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 ) ;
142
146
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
+ }
143
159
}
144
160
} ) ;
145
161
} catch ( error ) {
0 commit comments