memfs
memfs copied to clipboard
Auto-closing streams throw EBADF errors when the volume is cleared in the meantime
Hi,
I have a test which downloads a file with supertest and the file is served by setting the response body to read stream:
ctx.body = fs.createReadStream(filePath);
Then after the test finishes, I have a hook where I reset the memfs volume:
afterEach(() => {
vol.reset();
});
It looks like when the stream is being destroyed, it asynchronously calls the method to close the file, but the volume is already reset at that point, and it throws the error:
Error: EBADF: bad file descriptor, close
at createError ((...)/node_modules/memfs/lib/volume.js:121:17)
at Volume.getFileByFdOrThrow ((...)/node_modules/memfs/lib/volume.js:650:19)
at Volume.closeSync ((...)/node_modules/memfs/lib/volume.js:878:25)
at Immediate._onImmediate ((...)/node_modules/memfs/lib/volume.js:682:39)
at processImmediate (internal/timers.js:456:21)
Can it be avoided somehow in this case, by adding a check somewhere along those lines if the volume was reset in the meantime? Or do you maybe have any suggestion for me to work around it?
Could you await until the request completes in your test? So when vol.reset() is called the file is already closed.
Another approach could be to not use vol.reset() but in each test create its own volume.
test('...', async () => {
const vol = new Volume();
// ...
});
Thanks for all the suggestions,
Could you await until the request completes in your test? So when
vol.reset()is called the file is already closed.
I think I am already doing it... I am not sure here, but the destroy method of the memfs' readstream might be called asynchronously, after the request (and the test) is done 🤔
// import request from supertest, set up server (koa instance) in "before" hook etc.
// ...
it('downloads a file', async () => {
const fileRes = await request(server)
.get('/file/pixel.gif');
const localFile = fs.readFileSync('./test/files/pixel.gif');
assert.ok(localFile.equals(fileRes.body));
});
and I prefer to use one global "volume" here, to be reused both in the test and "on the other side" of the request... 🤔