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

fs.promises API is not working as in node #255

Open
fxdave opened this issue Jan 10, 2019 · 1 comment
Open

fs.promises API is not working as in node #255

fxdave opened this issue Jan 10, 2019 · 1 comment

Comments

@fxdave
Copy link

fxdave commented Jan 10, 2019

Introduction

The fs library of node provides an experimental feature: the fs/promises which has the same functionality but with promises.

The bug

import {promises as fsp} from 'fs'
fsp.readFile(SOME_VALID_URL, { encoding: 'utf8' })

Considering the code above, the readFile has 2 parameters: the url and the options.
In theory, the parameter options is default to {encoding:null, flag:'r'}.
The problem is that the flag won't be default if I run this with electron-webpack. But working if I run the code with node (and with babel of course). So with electron-webpack I get an exception:

NodeError: The value "undefined" is invalid for option "flags"
    at stringToFlags (internal/fs/utils.js:253:9)
    at open (internal/fs/promises.js:198:34)
    at Object.readFile (internal/fs/promises.js:466:20)
   ...

The stack trace doesn't tell so much but there's a function in promises.js:

async function readFile(path, options) {
  options = getOptions(options, { flag: 'r' });

  if (path instanceof FileHandle)
    return readFileHandle(path, options);

  const fd = await open(path, options.flag, 0o666);
  return readFileHandle(fd, options).finally(fd.close.bind(fd));
}

I tested and the getOptions(options, { flag: 'r' }) is giving back the options without modifications. Which is right because of the definition of getOptions:

function getOptions(options, defaultOptions) {
  if (options === null || options === undefined ||
      typeof options === 'function') {
    return defaultOptions;
  }

  if (typeof options === 'string') {
    defaultOptions = util._extend({}, defaultOptions);
    defaultOptions.encoding = options;
    options = defaultOptions;
  } else if (typeof options !== 'object') {
    throw new ERR_INVALID_ARG_TYPE('options', ['string', 'Object'], options);
  }

  if (options.encoding !== 'buffer')
    assertEncoding(options.encoding);
  return options;
}

By then, I don't really understand why is it working without electron-webpack. But the node documentation says it is correct to give object into the options.
https://nodejs.org/api/fs.html#fs_fspromises_readfile_path_options

Possible workaround

import {promises as fsp} from 'fs'
fsp.readFile(SOME_VALID_URL, { encoding: 'utf8' , flag: 'r'})
@fxdave fxdave changed the title fs.promises API is not working as in plain node fs.promises API is not working as in node Jan 10, 2019
@fxdave
Copy link
Author

fxdave commented Jan 11, 2019

I think the problem is the webpack because the source is outdated, I got this from the debugger:

async function readFile(path, options) {
  options = getOptions(options, { flag: 'r' });

  if (path instanceof FileHandle)
    return readFileHandle(path, options);

  const fd = await open(path, options.flag, 0o666);
  return readFileHandle(fd, options).finally(fd.close.bind(fd));
}

This should be:

async function readFile(path, options) {
  options = getOptions(options, { flag: 'r' });
  const flag = options.flag || 'r';

  if (path instanceof FileHandle)
    return readFileHandle(path, options);

  const fd = await open(path, flag, 0o666);
  return readFileHandle(fd, options).finally(fd.close.bind(fd));
}

Is it possible?

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

1 participant