Skip to content

Commit

Permalink
Wait until body file descriptor is open (#1054)
Browse files Browse the repository at this point in the history
  • Loading branch information
szmarczak committed Feb 6, 2020
1 parent b4a5402 commit 453a3a3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
18 changes: 12 additions & 6 deletions source/request-as-event-emitter.ts
@@ -1,3 +1,4 @@
import {ReadStream} from 'fs';
import CacheableRequest = require('cacheable-request');
import EventEmitter = require('events');
import http = require('http');
Expand All @@ -15,6 +16,7 @@ import {createProgressStream} from './progress';
import timedOut, {TimeoutError as TimedOutTimeoutError} from './utils/timed-out';
import {GeneralError, NormalizedOptions, Response, requestSymbol} from './types';
import urlToOptions from './utils/url-to-options';
import pEvent = require('p-event');

const setImmediateAsync = async (): Promise<void> => new Promise(resolve => setImmediate(resolve));
const pipeline = promisify(stream.pipeline);
Expand Down Expand Up @@ -301,13 +303,17 @@ export default (options: NormalizedOptions): RequestAsEventEmitter => {
};

(async () => {
// Promises are executed immediately.
// If there were no `setImmediate` here,
// `promise.json()` would have no effect
// as the request would be sent already.
await setImmediateAsync();

try {
if (options.body instanceof ReadStream) {
await pEvent(options.body, 'open');
}

// Promises are executed immediately.
// If there were no `setImmediate` here,
// `promise.json()` would have no effect
// as the request would be sent already.
await setImmediateAsync();

for (const hook of options.hooks.beforeRequest) {
// eslint-disable-next-line no-await-in-loop
await hook(options);
Expand Down
29 changes: 29 additions & 0 deletions test/post.ts
@@ -1,7 +1,10 @@
import {promisify} from 'util';
import stream = require('stream');
import fs = require('fs');
import test from 'ava';
import delay = require('delay');
import {Handler} from 'express';
import getStream = require('get-stream');
import toReadableStream = require('to-readable-stream');
import got from '../source';
import withServer from './helpers/with-server';
Expand Down Expand Up @@ -271,3 +274,29 @@ test('DELETE method sends plain objects as JSON', withServer, async (t, server,
});
t.deepEqual(body, {such: 'wow'});
});

test('catches body errors before calling pipeline() - promise', withServer, async (t, server, got) => {
server.post('/', defaultEndpoint);

await t.throwsAsync(got.post({
body: fs.createReadStream('./file-that-does-not-exist.txt')
}), {
message: /ENOENT: no such file or directory/
});

// Wait for unhandled errors
await delay(100);
});

test('catches body errors before calling pipeline() - stream', withServer, async (t, server, got) => {
server.post('/', defaultEndpoint);

await t.throwsAsync(getStream(got.stream.post({
body: fs.createReadStream('./file-that-does-not-exist.txt')
})), {
message: /ENOENT: no such file or directory/
});

// Wait for unhandled errors
await delay(100);
});

0 comments on commit 453a3a3

Please sign in to comment.