Skip to content

Commit

Permalink
fs: aggregate errors in fsPromises to avoid error swallowing
Browse files Browse the repository at this point in the history
Add AggregateError support to fsPromises, instead of
swallowing errors if fs.close throws.
  • Loading branch information
Linkgoron committed Apr 16, 2021
1 parent 369f239 commit cd8ac99
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions lib/internal/fs/promises.js
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ const {
ERR_METHOD_NOT_IMPLEMENTED,
},
AbortError,
aggregateTwoErrors,
} = require('internal/errors');
const { isArrayBufferView } = require('internal/util/types');
const { rimrafPromises } = require('internal/fs/rimraf');
@@ -250,6 +251,27 @@ class FileHandle extends EventEmitterMixin(JSTransferable) {
}
}

async function handleFdClose(fileOpPromise, closeFunc) {
let opError;
try {
return await fileOpPromise;
} catch (err) {
opError = err;
throw err;
} finally {
try {
await closeFunc();
} catch (closeError) {
if (!opError) {
// eslint-disable-next-line no-unsafe-finally
throw closeError;
}
// eslint-disable-next-line no-unsafe-finally
throw aggregateTwoErrors(closeError, opError);
}
}
}

async function fsCall(fn, handle, ...args) {
if (handle[kRefs] === undefined) {
throw new ERR_INVALID_ARG_TYPE('filehandle', 'FileHandle', handle);
@@ -498,7 +520,7 @@ async function rename(oldPath, newPath) {

async function truncate(path, len = 0) {
const fd = await open(path, 'r+');
return PromisePrototypeFinally(ftruncate(fd, len), fd.close);
return handleFdClose(ftruncate(fd, len), fd.close);
}

async function ftruncate(handle, len = 0) {
@@ -629,7 +651,7 @@ async function lchmod(path, mode) {
throw new ERR_METHOD_NOT_IMPLEMENTED('lchmod()');

const fd = await open(path, O_WRONLY | O_SYMLINK);
return PromisePrototypeFinally(fchmod(fd, mode), fd.close);
return handleFdClose(fchmod(fd, mode), fd.close);
}

async function lchown(path, uid, gid) {
@@ -708,7 +730,7 @@ async function writeFile(path, data, options) {
checkAborted(options.signal);

const fd = await open(path, flag, options.mode);
return PromisePrototypeFinally(
return handleFdClose(
writeFileHandle(fd, data, options.signal, options.encoding), fd.close);
}

@@ -733,7 +755,7 @@ async function readFile(path, options) {
checkAborted(options.signal);

const fd = await open(path, flag, 0o666);
return PromisePrototypeFinally(readFileHandle(fd, options), fd.close);
return handleFdClose(readFileHandle(fd, options), fd.close);
}

module.exports = {

0 comments on commit cd8ac99

Please sign in to comment.