Open lostfictions opened 3 years ago
I can reproduce the error in Nodejs v16, but not v14. Don't need to use jest to reproduce the bug. @Rugvip it looks there is edge case for fs.createReadStream, it tries to access the real file system.
const mockFs = require("mock-fs");
const fs = require("fs");
const { writeFile, unlink } = require("fs/promises");
const { join } = require("path");
const { tmpdir } = require("os");
mockFs();
// mockFs.restore();
async function test() {
const path = join(tmpdir(), `tmpfile-${Math.random()}.png`);
await writeFile(path, Buffer.from("whatever"));
const rs = fs.createReadStream(path);
// rs.close();
await unlink(path);
}
test().then(() => console.log("DONE"));
Error: ENOENT, no such file or directory '/var/folders/v_/y1wwsg8d7fvcr981nq9l89x00000gn/T/tmpfile-0.870533120229688.png'
Update: I found there is a very strange timing issue. My log shows the logic inside fs.createReadStream
seems being delayed after the await unlink(path)
, that's why it cannot find the file (it's already unlinked).
This can be approved with 2 ways:
await unlink(path);
.async function delay() {
return new Promise(resolve => {
setTimeout(resolve, 500);
});
}
// ...
await delay();
await unlink(path);
Since nodejs v14 has no such issue, there might be some bug or edge case in nodejs v16.
I can reproduce the same issue WITHOUT using mock-fs in nodejs v16.13.0, so this is probably an unexpected bug in nodejs v16+ itself.
const fs = require("fs");
const { writeFile, unlink } = require("fs/promises");
async function test() {
const path = `tmpfile-${Math.random()}.png`;
await writeFile(path, Buffer.from("whatever"));
const rs = fs.createReadStream(path);
// it doesn't matter whether we call close()
rs.close();
await unlink(path);
}
test().then(() => console.log("DONE"));
> node test.js
DONE
node:events:368
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, open 'tmpfile-0.16589223939625652.png'
Emitted 'error' event on ReadStream instance at:
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: 'tmpfile-0.16589223939625652.png'
}
Note the error is printed after "DONE" (means test() is resolved successfully...)
This also appears to be an issue impacting readFileSync. I tried to create a stream from a file loaded by readFileSync but I get the same ENOENT error.
Hi there, I'm trying mock-fs out. I might be misunderstanding, but it sounds like it creates an in-memory filesystem that can be written to as well as read from, right? Unfortunately, I seem to be getting an error when I write a file to the os tmpdir and then try to read it back via
createReadStream
. This works fine on the real filesystem.Here's a minimal repro, using mock-fs 5.1.0 and jest 27.2.1.
Here's the output I get:
Commenting out
const rs = createReadStream(path); rs.close();
causes the test to pass.