Skip to content

Commit b070ee8

Browse files
committed
fixup! fixup! fs: aggregate errors in fsPromises to avoid error swallowing
1 parent 55961b8 commit b070ee8

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
// Flags: --expose-internals
3+
4+
const common = require('../common');
5+
const tmpdir = require('../common/tmpdir');
6+
7+
// The following tests validate aggregate errors are thrown correctly
8+
// when both an operation and close throw.
9+
10+
const fs = require('fs');
11+
const path = require('path');
12+
const {
13+
readFile,
14+
writeFile,
15+
truncate,
16+
lchmod,
17+
} = fs.promises;
18+
const {
19+
FileHandle,
20+
} = require('internal/fs/promises');
21+
22+
const assert = require('assert');
23+
const originalFd = Object.getOwnPropertyDescriptor(FileHandle.prototype, 'fd');
24+
25+
let count = 0;
26+
async function createFile() {
27+
const filePath = path.join(tmpdir.path, `aggregate_errors_${++count}.txt`);
28+
await writeFile(filePath, 'content');
29+
return filePath;
30+
}
31+
32+
async function checkAggregateError(op) {
33+
try {
34+
const filePath = await createFile();
35+
Object.defineProperty(FileHandle.prototype, 'fd', {
36+
get: function() {
37+
// Close is set by using a setter,
38+
// so it needs to be set on the instance.
39+
const originalClose = this.close;
40+
this.close = async () => {
41+
// close the file
42+
await originalClose.call(this);
43+
const closeError = new Error('CLOSE_ERROR');
44+
closeError.code = 456;
45+
throw closeError;
46+
};
47+
const opError = new Error('INTERNAL_ERROR');
48+
opError.code = 123;
49+
throw opError;
50+
}
51+
});
52+
53+
await op(filePath).catch(common.mustCall((err) => {
54+
assert.strictEqual(err.constructor.name, 'AggregateError');
55+
assert.strictEqual(err.code, 123);
56+
assert.strictEqual(err.errors.length, 2);
57+
assert.strictEqual(err.errors[0].message, 'INTERNAL_ERROR');
58+
assert.strictEqual(err.errors[1].message, 'CLOSE_ERROR');
59+
}));
60+
} finally {
61+
Object.defineProperty(FileHandle.prototype, 'fd', originalFd);
62+
}
63+
}
64+
(async function() {
65+
tmpdir.refresh();
66+
await checkAggregateError((filePath) => truncate(filePath));
67+
await checkAggregateError((filePath) => readFile(filePath));
68+
await checkAggregateError((filePath) => writeFile(filePath, '123'));
69+
if (common.isOSX) {
70+
await checkAggregateError((filePath) => lchmod(filePath, 0o777));
71+
}
72+
})().then(common.mustCall());

0 commit comments

Comments
 (0)