Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error STATUS_FILE_CLOSED after pipe stream created with createReadStream #82

Open
julien13630 opened this issue Feb 9, 2022 · 7 comments

Comments

@julien13630
Copy link

julien13630 commented Feb 9, 2022

Hi,

I have an error when i'm reading list of file using readstream.
I have a loop on all file of a dir.
For each file I create a read stream that I pipe to a csv parser streamwritter (https://www.npmjs.com/package/csv-parser).
File is read well but when at the end of loop an error STATUS_FILE_CLOSED occures :

[...]

for (let file of files) {
            try {
                if(file.isDirectory())
                {
                    continue;
                }
                var rs = await smb2Client.createReadStream('dummy\\path\\test\\' + file.name,);
                rows.push(...await manageCsvFile(rs));
            } catch (e) {
                console.log('error on file' + file.name, e)
            }
}
[...]

--------

async function manageCsvFile(rs) {
    let rows = [];
    var fd = rs.pipe(csv({
        separator: ';'
    }));
    var end = new Promise(function(resolve, reject) {
        fd.on('data', (row) => {
            rows.push(row);
        })
        fd.on('end', () => {
            console.log('CSV file successfully processed');
        })
        fd.on('close', () => {
            console.log('Stream has been destroyed and file has been closed');
            resolve();
        });
    });
    await end;
    return rows;
}

----ERROR Message

"errorType": "Error",
  "errorMessage": "STATUS_FILE_CLOSED (0xC0000128) : An I/O request other than close and several other special case operations was attempted using a file object that had already been closed.",
  "trace": [
    "Error: STATUS_FILE_CLOSED (0xC0000128) : An I/O request other than close and several other special case operations was attempted using a file object that had already been closed.",
    "    at SMB2Forge.request (/var/task/node_modules/@marsaud/smb2/lib/tools/smb2-forge.js:22:15)",
    "    at Readable.stream._destroy (/var/task/node_modules/@marsaud/smb2/lib/api/createReadStream.js:42:9)",
    "    at Readable.destroy (internal/streams/destroy.js:39:8)",
    "    at endReadableNT (internal/streams/readable.js:1350:16)",
    "    at processTicksAndRejections (internal/process/task_queues.js:82:21)"
  ]

Can you help me on this issue ?
Best regards

@brunocw-cit
Copy link

Also affecting me. Although it looks like the file is being read thoroughly

@mbrowng
Copy link

mbrowng commented Jun 30, 2022

The same is happening to me, and as @brunocw-cit said, the file is being read.

Any help?

@brunocw-cit
Copy link

hey @mbrowng i know its not ideal (if you're reading a large file) but what worked for me was using 'await smb2client.readFile' instead of 'createReadStream' to read my file all at once instead of streaming it.

@Akxe
Copy link

Akxe commented Nov 30, 2022

So!... I have found out how to hide this error while (hopefully) not destroying anything else!

const stream = await smb2Client.createReadStream(path);
res.contentType(extname(path));
stream.pipe(res).once('drain', () => stream._destroy = () => { });

I know this looks scary, but the stream gets closed twice. Replacing _destroy method that calls the second close event solved the issue. To validate the claim, you can also look for "close" and "finished" events, where you will see that stream.destroyed is true.

@lschipper-VW
Copy link

Do we have an update on this? Seems to be happening when I upgrade to node ~>=16

@jackaperkins
Copy link

@Akxe i tried your fix, but i'm still seeing the error. the stream does seem to work fine despite this.

If anyone else sees this or has a solution for streaming files over SMB in node in 2023 I'd be much obliged!

my demo code which returns the file's contents over simple http server

import SMB2 from '@marsaud/smb2'
import http from 'node:http'

let smb2Client = new SMB2({
  share: '\\\\localhost\\public',
  domain: 'somedomain',
  username: 'myuser',
  password: 'mypass'
})

let server = http.createServer(async (req, res) => {
  console.log(`Request for ${req.method} - ${req.url}`)
  let filePath = 'folder/test_file'

  let stream = await smb2Client.createReadStream(filePath)
  
  res.write('some value from SMB:')
  stream.pipe(res).once('drain', () => stream._destroy = () => { console.log('closing a second time?') })
})

server.listen(3000, () => console.log('listening on 3000'))

@siddiq-rehman
Copy link

siddiq-rehman commented Mar 5, 2024

It worked for me, By using SmbClient.Open to get the fd descriptor.

Then using the file descriptor for opening the file for stream and chosing option "autoClose"

Then once the file is read, closing the fd by yourself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants