diff --git a/lib/util/__tests__/utimes.test.js b/lib/util/__tests__/utimes.test.js index 02c65d1f..eaab1adb 100644 --- a/lib/util/__tests__/utimes.test.js +++ b/lib/util/__tests__/utimes.test.js @@ -97,4 +97,26 @@ describe('utimes', () => { }) }) }) + + describe('utimesMillisSync()', () => { + it('should close open file descriptors after encountering an error', () => { + const fakeFd = Math.random() + + gracefulFsStub.openSync = (pathIgnored, flagsIgnored) => fakeFd + + let closeCalled = false + gracefulFsStub.closeSync = (fd) => { + assert.strictEqual(fd, fakeFd) + closeCalled = true + } + + const testError = new Error('A test error') + gracefulFsStub.futimesSync = (fd, atimeIgnored, mtimeIgnored) => { + throw testError + } + + assert.throws(() => utimes.utimesMillisSync('ignored', 'ignored', 'ignored'), testError) + assert(closeCalled) + }) + }) }) diff --git a/lib/util/utimes.js b/lib/util/utimes.js index 434b3cea..55ad9132 100644 --- a/lib/util/utimes.js +++ b/lib/util/utimes.js @@ -27,8 +27,24 @@ async function utimesMillis (path, atime, mtime) { function utimesMillisSync (path, atime, mtime) { const fd = fs.openSync(path, 'r+') - fs.futimesSync(fd, atime, mtime) - return fs.closeSync(fd) + + let error = null + + try { + fs.futimesSync(fd, atime, mtime) + } catch (futimesErr) { + error = futimesErr + } finally { + try { + fs.closeSync(fd) + } catch (closeErr) { + error = closeErr + } + } + + if (error) { + throw error + } } module.exports = {