branisha
branisha

Reputation: 96

Node js FileHandle read method throws invalid argument error

According to Node docs, FileHandle.read() takes two types of arguments, multiple objects, or one object. However, when I pass object, I get: TypeError [ERR_INVALID_ARG_TYPE]: The "buffer" argument must be an instance of Buffer, TypedArray, or DataView. Received an instance of Object.

Docs reference is here for regular read and here for "object" read.

"Object" read says that it was added in: v13.11.0. I'm using v14.4.0.

Here is code I'm using:

    fs_p.open(FILENAME, 'r')
        .then((fileHandler) => {
            console.log(fileHandler);
            const dyn_head = Buffer.alloc(12);

            fileHandler.read({ buffer: dyn_head })
                .then((bytesRead, buffer) => {
                    console.log("Reading")
                }).catch((err) => {
                    console.log(err)
                });

        }).catch((err) => {
            console.log("err")
        });

fs_p is fs.promises.

In case that you are wondering why I'm using "object" read, I sometimes won't use all parameters, and I want to make code clean.

If it helps. I'm on Linux.

Upvotes: 0

Views: 1563

Answers (1)

jfriend00
jfriend00

Reputation: 708116

So, that form of .read() just does not work in node v14. I traced into it in the debugger and it goes right to this code:

https://github.com/nodejs/node/blob/master/lib/internal/fs/promises.js#L251

async function read(handle, buffer, offset, length, position) {
  validateFileHandle(handle);
  validateBuffer(buffer);            // <== fails here

  if (offset == null) {
    offset = 0;
  } else {
    validateInteger(offset, 'offset');
  }

  length |= 0;

  if (length === 0)
    return { bytesRead: length, buffer };

  if (buffer.length === 0) {
    throw new ERR_INVALID_ARG_VALUE('buffer', buffer,
                                    'is empty and cannot be written');
  }

  validateOffsetLengthRead(offset, length, buffer.length);

  if (!NumberIsSafeInteger(position))
    position = -1;

  const bytesRead = (await binding.read(handle.fd, buffer, offset, length,
                                        position, kUsePromises)) || 0;

  return { bytesRead, buffer };
}

And, the call to validateBuffer() throws immediately if you try to use the handle.read(options) form. So, this appears to just be a bug (in either the doc or the implementation, I'm not sure which). In any case, you will just have to switch to the other form of .read() where you pass each argument separately.

Your code will work if you change from this:

fileHandler.read({ buffer: dyn_head }).then((bytesRead, buffer) => {

to this:

fileHandler.read(dyn_head, 0, dyn_head.length, 0).then(({bytesRead, buffer}) => {

Note, that you also have to change your .then() as your arguments were wrong there too. That wasn't the cause of the problem you write about because you weren't getting there yet, but you also have to fix that.


P.S. I tried searching for an open bug report on this issue, but did not find one, though I'm not sure I really know how to search nodejs bugs very well. Perhaps you should file a bug report.

Upvotes: 1

Related Questions