Skip to content

Commit a794bea

Browse files
committed
fs: aggregate errors in fsPromises to avoid error swallowing
Add AggregateError support to fsPromises, instead of swallowing errors if fs.close throws.
1 parent 05df701 commit a794bea

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

lib/internal/fs/promises.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const {
3333
ERR_METHOD_NOT_IMPLEMENTED,
3434
},
3535
AbortError,
36+
aggregateTwoErrors,
3637
} = require('internal/errors');
3738
const { isArrayBufferView } = require('internal/util/types');
3839
const { rimrafPromises } = require('internal/fs/rimraf');
@@ -250,6 +251,27 @@ class FileHandle extends EventEmitterMixin(JSTransferable) {
250251
}
251252
}
252253

254+
async function handleFdClose(fileOpPromise, closeFunc) {
255+
let opError;
256+
try {
257+
return await fileOpPromise;
258+
} catch (err) {
259+
opError = err;
260+
throw err;
261+
} finally {
262+
try {
263+
await closeFunc();
264+
} catch (closeError) {
265+
if (!opError) {
266+
// eslint-disable-next-line no-unsafe-finally
267+
throw closeError;
268+
}
269+
// eslint-disable-next-line no-unsafe-finally
270+
throw aggregateTwoErrors(closeError, opError);
271+
}
272+
}
273+
}
274+
253275
async function fsCall(fn, handle, ...args) {
254276
if (handle[kRefs] === undefined) {
255277
throw new ERR_INVALID_ARG_TYPE('filehandle', 'FileHandle', handle);
@@ -498,7 +520,7 @@ async function rename(oldPath, newPath) {
498520

499521
async function truncate(path, len = 0) {
500522
const fd = await open(path, 'r+');
501-
return PromisePrototypeFinally(ftruncate(fd, len), fd.close);
523+
return handleFdClose(ftruncate(fd, len), fd.close);
502524
}
503525

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

631653
const fd = await open(path, O_WRONLY | O_SYMLINK);
632-
return PromisePrototypeFinally(fchmod(fd, mode), fd.close);
654+
return handleFdClose(fchmod(fd, mode), fd.close);
633655
}
634656

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

710732
const fd = await open(path, flag, options.mode);
711-
return PromisePrototypeFinally(
733+
return handleFdClose(
712734
writeFileHandle(fd, data, options.signal, options.encoding), fd.close);
713735
}
714736

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

735757
const fd = await open(path, flag, 0o666);
736-
return PromisePrototypeFinally(readFileHandle(fd, options), fd.close);
758+
return handleFdClose(readFileHandle(fd, options), fd.close);
737759
}
738760

739761
module.exports = {

0 commit comments

Comments
 (0)