Got: Form-Data POST with DNS errors throws unhandled rejection

Created on 2 Jul 2020  路  4Comments  路  Source: sindresorhus/got

Describe the bug

  • got version: 11.3.0
  • Node.js version: 12.18.2
  • OS & version: Ubuntu 18.04.4

Actual behavior

Trying to make a request to a domain that will throw an error (e.g. DNS error) with a FormData with a file readable stream throws an unhandled promise rejection.

I found https://github.com/sindresorhus/got/issues/1282, but it should not apply here, since I am not using the retry feature.

Expected behavior

The promise should be rejected with the RequestError.

Code to reproduce

const fs = require('fs');
const FormData = require('form-data');
const got = require('got');

const form = new FormData();
form.append('name', 'foo');
form.append('file', fs.createReadStream(__filename));

got('http://bogusdomainfake.com/foo', {
    body: form,
    method: 'POST',
    retry: {
        limit: 0,
    },
}).catch(err => {
    console.error('catch err', err.message);
});
$ node test.js
catch err getaddrinfo ENOTFOUND bogusdomainfake.com
(node:31896) UnhandledPromiseRejectionWarning: RequestError: getaddrinfo ENOTFOUND bogusdomainfake.com
    at ClientRequest.<anonymous> (/home/dev/node_modules/got/dist/source/core/index.js:826:25)
    at Object.onceWrapper (events.js:422:26)
    at ClientRequest.emit (events.js:327:22)
    at ClientRequest.origin.emit (/home/dev/node_modules/@szmarczak/http-timer/dist/source/index.js:39:20)
    at Socket.socketErrorListener (_http_client.js:426:9)
    at Socket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26)
(node:31896) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:31896) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Commenting out the line with body: form or form.append('file', fs.createReadStream(__filename)), results in the following expected result:

$ node test.js
catch err getaddrinfo ENOTFOUND bogusdomainfake.com

Checklist

  • [x] I have read the documentation.
  • [x] I have tried my code with the latest version of Node.js and Got.
bug external

All 4 comments

Almost identical error for streams:

got.stream('http://bogusdomainfake.com/foo', {
    body: form,
    method: 'POST',
    retry: {
        limit: 0,
    },
}).once('error', () => {
    console.log('got error');
});

This is not actually Got's fault. The issue belongs to ~form-data~ combined-stream.

const stream = require('stream');
const CombinedStream = require('combined-stream');
const fs = require('fs');

const a = new stream.PassThrough();
const b = new CombinedStream();

// Change this to `on` and it will pass, although it still logs only once.
a.once('error', () => {
    console.log('a errored');
});

const c = new stream.PassThrough();
b.append(c);

b.pipe(a);
a.destroy(new Error('nope.'));

Closing (housekeeping).

For those will arrive at this page, since the bug was not fixed in dependency module form-data #475 yet (as of 2020-11-17), you may consider to use another library formdata-node instead of form-data (which I did to save time).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AxelTerizaki picture AxelTerizaki  路  3Comments

framerate picture framerate  路  4Comments

carvallegro picture carvallegro  路  4Comments

f-mer picture f-mer  路  4Comments

jamestalmage picture jamestalmage  路  3Comments