From 4b605137796f275f4aff3cd0481c78ca153aaf51 Mon Sep 17 00:00:00 2001 From: ywong Date: Wed, 17 May 2017 19:27:53 +1000 Subject: [PATCH] fix(preprocessor): retry if fs.readFile fails --- lib/preprocessor.js | 18 ++++++++++--- test/unit/preprocessor.spec.js | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 860bcdbdc..8111491bf 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -75,10 +75,19 @@ var createPreprocessor = function (config, basePath, injector) { return function preprocess (file, done) { patterns = Object.keys(config) - - return fs.readFile(file.originalPath, function (err, buffer) { + var retryCount = 0 + var maxRetries = 3 + function handleFile (err, buffer) { if (err) { - throw err + log.warn(err) + if (retryCount < maxRetries) { + retryCount++ + log.warn('retrying ' + retryCount) + fs.readFile(file.originalPath, handleFile) + return + } else { + done() + } } isBinaryFile(buffer, buffer.length, function (err, thisFileIsBinary) { @@ -121,7 +130,8 @@ var createPreprocessor = function (config, basePath, injector) { nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString()) }) - }) + } + return fs.readFile(file.originalPath, handleFile) } } createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector'] diff --git a/test/unit/preprocessor.spec.js b/test/unit/preprocessor.spec.js index c0974e6a1..0336308fe 100644 --- a/test/unit/preprocessor.spec.js +++ b/test/unit/preprocessor.spec.js @@ -229,6 +229,54 @@ describe('preprocessor', () => { }) }) + describe('when fs.readFile fails', () => { + var file = {originalPath: '/some/a.js', path: 'path'} + var getReadFileCallback = (nthCall) => { + return mockFs.readFile.args[nthCall][1] + } + + beforeEach(() => { + sinon.stub(mockFs, 'readFile') + }) + + it('should retry up to 3 times', (done) => { + var fakePreprocessor = sinon.spy((content, file, done) => { + done(null, content) + }) + + var injector = new di.Injector([{ + 'preprocessor:fake': ['factory', () => fakePreprocessor] + }, emitterSetting]) + + var pp = m.createPreprocessor({'**/*.js': ['fake']}, null, injector) + + pp(file, () => { + expect(fakePreprocessor).to.have.been.called + done() + }) + getReadFileCallback(0)('error') + getReadFileCallback(1)('error') + var thirdCallback = getReadFileCallback(2) + mockFs.readFile.restore() + thirdCallback('error') + }) + + it('should abort after 3 retries', (done) => { + var injector = new di.Injector([{}, emitterSetting]) + + var pp = m.createPreprocessor({'**/*.js': []}, null, injector) + + pp(file, () => { + done() + }) + + getReadFileCallback(0)('error') + getReadFileCallback(1)('error') + getReadFileCallback(2)('error') + getReadFileCallback(3)('error') + }) + }) + it('should not preprocess binary files', (done) => { var fakePreprocessor = sinon.spy((content, file, done) => { done(null, content)