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.
The promise should be rejected with the RequestError.
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
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).