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 05df701 commit a794bea
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
Expand Up @@ -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');
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}

Expand All @@ -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 = {
Expand Down

0 comments on commit a794bea

Please sign in to comment.