Преглед изворни кода

Delete temporary file when error in writing to stream

Simon Detheridge пре 6 година
родитељ
комит
25f1c2bfc4

+ 12 - 1
services/filestore/app/js/LocalFileWriter.js

@@ -32,6 +32,8 @@ async function writeStream(stream, key) {
     logger.log({ fsPath }, 'finished writing file locally')
     return fsPath
   } catch (err) {
+    await deleteFile(fsPath)
+
     logger.err({ err, fsPath }, 'problem writing file locally')
     throw new WriteError({
       message: 'problem writing file locally',
@@ -45,7 +47,16 @@ async function deleteFile(fsPath) {
     return
   }
   logger.log({ fsPath }, 'removing local temp file')
-  await promisify(fs.unlink)(fsPath)
+  try {
+    await promisify(fs.unlink)(fsPath)
+  } catch (err) {
+    if (err.code !== 'ENOENT') {
+      throw new WriteError({
+        message: 'failed to delete file',
+        info: { fsPath }
+      }).withCause(err)
+    }
+  }
 }
 
 function _getPath(key) {

+ 39 - 7
services/filestore/test/unit/js/LocalFileWriterTests.js

@@ -49,6 +49,26 @@ describe('LocalFileWriter', function() {
         done()
       })
     })
+
+    describe('when there is an error', function() {
+      const error = new Error('not enough ketchup')
+      beforeEach(function() {
+        stream.pipeline.yields(error)
+      })
+
+      it('should wrap the error', function() {
+        LocalFileWriter.writeStream(readStream, filename, err => {
+          expect(err).to.exist
+          expect(err.cause).to.equal(error)
+        })
+      })
+
+      it('should delete the temporary file', function() {
+        LocalFileWriter.writeStream(readStream, filename, () => {
+          expect(fs.unlink).to.have.been.calledWith(fsPath)
+        })
+      })
+    })
   })
 
   describe('deleteFile', function() {
@@ -60,18 +80,30 @@ describe('LocalFileWriter', function() {
       })
     })
 
-    it('should not do anything if called with an empty path', function(done) {
-      fs.unlink = sinon.stub().yields(new Error('failed to reticulate splines'))
-      LocalFileWriter.deleteFile(fsPath, err => {
-        expect(err).to.exist
+    it('should not call unlink with an empty path', function(done) {
+      LocalFileWriter.deleteFile('', err => {
+        expect(err).not.to.exist
+        expect(fs.unlink).not.to.have.been.called
         done()
       })
     })
 
-    it('should not call unlink with an empty path', function(done) {
-      LocalFileWriter.deleteFile('', err => {
+    it('should not throw a error if the file does not exist', function(done) {
+      const error = new Error('file not found')
+      error.code = 'ENOENT'
+      fs.unlink = sinon.stub().yields(error)
+      LocalFileWriter.deleteFile(fsPath, err => {
         expect(err).not.to.exist
-        expect(fs.unlink).not.to.have.been.called
+        done()
+      })
+    })
+
+    it('should wrap the error', function(done) {
+      const error = new Error('failed to reticulate splines')
+      fs.unlink = sinon.stub().yields(error)
+      LocalFileWriter.deleteFile(fsPath, err => {
+        expect(err).to.exist
+        expect(err.cause).to.equal(error)
         done()
       })
     })