sindresorhus / got

🌐 Human-friendly and powerful HTTP request library for Node.js
MIT License
14.27k stars 935 forks source link

FormData example not working with v12 #1907

Closed gouku closed 2 years ago

gouku commented 3 years ago

Describe the bug

The code is copied directly for the example without changes: https://github.com/sindresorhus/got/blob/main/documentation/2-options.md#body

I tried all v12 versions seems none of them work as expected.

Actual behavior

Error thrown:

node:internal/process/esm_loader:74
    internalBinding('errors').triggerUncaughtException(
                              ^

RequestError: Expected value which is `predicate returns truthy for any value`, received values of types `FormData`.
    at Request._destroy (file:///Users/ww/Code/got-test/node_modules/got/dist/source/core/index.js:464:21)
    at _destroy (node:internal/streams/destroy:102:25)
    at Request.destroy (node:internal/streams/destroy:64:5)
    at Request.flush (file:///Users/ww/Code/got-test/node_modules/got/dist/source/core/index.js:241:22)
    at lastHandler (file:///Users/ww/Code/got-test/node_modules/got/dist/source/create.js:37:26)
    at iterateHandlers (file:///Users/ww/Code/got-test/node_modules/got/dist/source/create.js:49:28)
    at got (file:///Users/ww/Code/got-test/node_modules/got/dist/source/create.js:69:16)
    at Function.got.<computed> [as post] (file:///Users/ww/Code/got-test/node_modules/got/dist/source/create.js:172:42)
    at file:///Users/ww/Code/got-test/index.js:8:24
    at assertType (/Users/ww/Code/got-test/node_modules/@sindresorhus/is/dist/index.js:299:15)
    at Object.any (/Users/ww/Code/got-test/node_modules/@sindresorhus/is/dist/index.js:395:16)
    at Options.set body [as body] (file:///Users/ww/Code/got-test/node_modules/got/dist/source/core/options.js:605:16)
    at Options.merge (file:///Users/ww/Code/got-test/node_modules/got/dist/source/core/options.js:404:27)
    at new Options (file:///Users/ww/Code/got-test/node_modules/got/dist/source/core/options.js:348:26)
    at new Request (file:///Users/ww/Code/got-test/node_modules/got/dist/source/core/index.js:225:28)
    at got (file:///Users/ww/Code/got-test/node_modules/got/dist/source/create.js:31:25)
    at Function.got.<computed> [as post] (file:///Users/ww/Code/got-test/node_modules/got/dist/source/create.js:172:42)
    at file:///Users/ww/Code/got-test/index.js:8:24
    at ModuleJob.run (node:internal/modules/esm/module_job:183:25) {
  input: undefined,
  code: 'ERR_GOT_REQUEST_ERROR',
  timings: undefined,
  options: Options {
    _unixOptions: undefined,
    _internals: {
      request: undefined,
      agent: { http: undefined, https: undefined, http2: undefined },
      h2session: undefined,
      decompress: true,
      timeout: {
        connect: undefined,
        lookup: undefined,
        read: undefined,
        request: undefined,
        response: undefined,
        secureConnect: undefined,
        send: undefined,
        socket: undefined
      },
      prefixUrl: '',
      body: undefined,
      form: undefined,
      json: undefined,
      cookieJar: undefined,
      ignoreInvalidCookies: false,
      searchParams: undefined,
      dnsLookup: undefined,
      dnsCache: undefined,
      context: {},
      hooks: {
        init: [],
        beforeRequest: [],
        beforeError: [],
        beforeRedirect: [],
        beforeRetry: [],
        afterResponse: []
      },
      followRedirect: true,
      maxRedirects: 10,
      cache: undefined,
      throwHttpErrors: true,
      username: '',
      password: '',
      http2: false,
      allowGetBody: false,
      headers: {
        'user-agent': 'got (https://github.com/sindresorhus/got)',
        accept: 'application/json'
      },
      methodRewriting: false,
      dnsLookupIpVersion: undefined,
      parseJson: [Function: parse],
      stringifyJson: [Function: stringify],
      retry: {
        limit: 2,
        methods: [ 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE' ],
        statusCodes: [
          408, 413, 429, 500,
          502, 503, 504, 521,
          522, 524
        ],
        errorCodes: [
          'ETIMEDOUT',
          'ECONNRESET',
          'EADDRINUSE',
          'ECONNREFUSED',
          'EPIPE',
          'ENOTFOUND',
          'ENETUNREACH',
          'EAI_AGAIN'
        ],
        maxRetryAfter: undefined,
        calculateDelay: [Function: calculateDelay],
        backoffLimit: Infinity,
        noise: 100
      },
      localAddress: undefined,
      method: 'GET',
      createConnection: undefined,
      cacheOptions: {
        shared: undefined,
        cacheHeuristic: undefined,
        immutableMinTimeToLive: undefined,
        ignoreCargoCult: undefined
      },
      https: {
        alpnProtocols: undefined,
        rejectUnauthorized: undefined,
        checkServerIdentity: undefined,
        certificateAuthority: undefined,
        key: undefined,
        certificate: undefined,
        passphrase: undefined,
        pfx: undefined,
        ciphers: undefined,
        honorCipherOrder: undefined,
        minVersion: undefined,
        maxVersion: undefined,
        signatureAlgorithms: undefined,
        tlsSessionLifetime: undefined,
        dhparam: undefined,
        ecdhCurve: undefined,
        certificateRevocationLists: undefined
      },
      encoding: undefined,
      resolveBodyOnly: false,
      isStream: false,
      responseType: 'text',
      url: <ref *1> URL {
        [Symbol(context)]: URLContext {
          flags: 400,
          scheme: 'https:',
          username: '',
          password: '',
          host: 'httpbin.org',
          port: null,
          path: [ 'post' ],
          query: null,
          fragment: null
        },
        [Symbol(query)]: URLSearchParams {
          [Symbol(query)]: [],
          [Symbol(context)]: [Circular *1]
        }
      },
      pagination: {
        transform: [Function: transform],
        paginate: [Function: paginate],
        filter: [Function: filter],
        shouldContinue: [Function: shouldContinue],
        countLimit: Infinity,
        backoff: 0,
        requestLimit: 10000,
        stackAllItems: false
      },
      setHost: true,
      maxHeaderSize: undefined
    },
    _merging: false,
    _init: []
  }

Expected behavior

Hello, world!

Code to reproduce

package.json:

{
  "name": "got-test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "type": "module",
  "dependencies": {
    "formdata-node": "^4.3.1",
    "formdata-polyfill": "^4.0.10",
    "got": "^12.0.0-beta.4"
  }
}

index.js

import got from 'got';
import {FormData} from 'formdata-node'; // or:
// import {FormData} from 'formdata-polyfill/esm.min.js';

const form = new FormData();
form.set('greeting', 'Hello, world!');

const data = await got.post('https://httpbin.org/post', {
    body: form
}).json();

console.log(data.form.greeting);
//=> 'Hello, world!'

Checklist

octet-stream commented 2 years ago

FormData support is not released yet. See: https://github.com/sindresorhus/got/discussions/1877

gouku commented 2 years ago

Please add a note in the documentation that this feature is not yet finished. I was debugging for it for hours only found it was not supported yet.

octet-stream commented 2 years ago

You can find a workaround by the link I posted above.

szmarczak commented 2 years ago

Please add a note in the documentation that this feature is not yet finished.

Please use the appropriate docs for stable version instead. The current branch is for development.

szmarczak commented 2 years ago

Released got@12.0.0 :tada: