Skip to content

Commit

Permalink
Prevent uncaught exception in some cases (sindresorhus#459)
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwouter authored and szmarczak committed Mar 7, 2018
1 parent 558f8d8 commit 8afbe4e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 77 deletions.
110 changes: 59 additions & 51 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,59 +142,12 @@ function requestAsEventEmitter(opts) {
return;
}

const downloadBodySize = Number(res.headers['content-length']) || null;
let downloaded = 0;

setImmediate(() => {
const progressStream = new Transform({
transform(chunk, encoding, callback) {
downloaded += chunk.length;

const percent = downloadBodySize ? downloaded / downloadBodySize : 0;

// Let flush() be responsible for emitting the last event
if (percent < 1) {
ee.emit('downloadProgress', {
percent,
transferred: downloaded,
total: downloadBodySize
});
}

callback(null, chunk);
},

flush(callback) {
ee.emit('downloadProgress', {
percent: 1,
transferred: downloaded,
total: downloadBodySize
});

callback();
}
});

mimicResponse(res, progressStream);
progressStream.redirectUrls = redirects;

const response = opts.decompress === true &&
is.function(decompressResponse) &&
opts.method !== 'HEAD' ? decompressResponse(progressStream) : progressStream;

if (!opts.decompress && ['gzip', 'deflate'].indexOf(res.headers['content-encoding']) !== -1) {
opts.encoding = null;
try {
getResponse(res, opts, ee, redirects);
} catch (e) {
ee.emit('error', e);
}

ee.emit('response', response);

ee.emit('downloadProgress', {
percent: 0,
transferred: 0,
total: downloadBodySize
});

res.pipe(progressStream);
});
});

Expand Down Expand Up @@ -306,6 +259,61 @@ function requestAsEventEmitter(opts) {
return ee;
}

function getResponse(res, opts, ee, redirects) {
const downloadBodySize = Number(res.headers['content-length']) || null;
let downloaded = 0;

const progressStream = new Transform({
transform(chunk, encoding, callback) {
downloaded += chunk.length;

const percent = downloadBodySize ? downloaded / downloadBodySize : 0;

// Let flush() be responsible for emitting the last event
if (percent < 1) {
ee.emit('downloadProgress', {
percent,
transferred: downloaded,
total: downloadBodySize
});
}

callback(null, chunk);
},

flush(callback) {
ee.emit('downloadProgress', {
percent: 1,
transferred: downloaded,
total: downloadBodySize
});

callback();
}
});

mimicResponse(res, progressStream);
progressStream.redirectUrls = redirects;

const response = opts.decompress === true &&
is.function(decompressResponse) &&
opts.method !== 'HEAD' ? decompressResponse(progressStream) : progressStream;

if (!opts.decompress && ['gzip', 'deflate'].indexOf(res.headers['content-encoding']) !== -1) {
opts.encoding = null;
}

ee.emit('response', response);

ee.emit('downloadProgress', {
percent: 0,
transferred: 0,
total: downloadBodySize
});

res.pipe(progressStream);
}

function asPromise(opts) {
const timeoutFn = requestPromise => opts.gotTimeout && opts.gotTimeout.request ?
pTimeout(requestPromise, opts.gotTimeout.request, new got.RequestError({message: 'Request timed out', code: 'ETIMEDOUT'}, opts)) :
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"nyc": "^11.0.2",
"p-event": "^1.3.0",
"pem": "^1.4.4",
"proxyquire": "^1.8.0",
"sinon": "^4.0.0",
"slow-stream": "0.0.4",
"tempfile": "^2.0.0",
Expand Down
14 changes: 13 additions & 1 deletion test/error.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import http from 'http';
import test from 'ava';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
import got from '..';
import {createServer} from './helpers/server';

Expand Down Expand Up @@ -52,7 +53,7 @@ test('dns message', async t => {
});

test('options.body error message', async t => {
const err = await t.throws(got(s.url, {body: () => {}}));
const err = await t.throws(got(s.url, {body: () => { }}));
t.regex(err.message, /The `body` option must be a stream\.Readable, string, Buffer or plain Object/);
});

Expand All @@ -78,6 +79,17 @@ test.serial('http.request error', async t => {
stub.restore();
});

test.serial('catch error in mimicResponse', async t => {
const proxiedGot = proxyquire('..', {
'mimic-response'() {
throw new Error('Error in mimic-response');
}
});

const err = await t.throws(proxiedGot(s.url));
t.is(err.message, 'Error in mimic-response');
});

test.after('cleanup', async () => {
await s.close();
});
52 changes: 27 additions & 25 deletions test/unix-socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,37 @@ const socketPath = tempy.file({extension: 'socket'});

let s;

test.before('setup', async () => {
s = await createServer();
if (process.platform !== 'win32') {
test.before('setup', async () => {
s = await createServer();

s.on('/', (req, res) => {
res.end('ok');
});
s.on('/', (req, res) => {
res.end('ok');
});

s.on('/foo:bar', (req, res) => {
res.end('ok');
});
s.on('/foo:bar', (req, res) => {
res.end('ok');
});

await s.listen(socketPath);
});
await s.listen(socketPath);
});

test('works', async t => {
const url = format('http://unix:%s:%s', socketPath, '/');
t.is((await got(url)).body, 'ok');
});
test('works', async t => {
const url = format('http://unix:%s:%s', socketPath, '/');
t.is((await got(url)).body, 'ok');
});

test('protocol-less works', async t => {
const url = format('unix:%s:%s', socketPath, '/');
t.is((await got(url)).body, 'ok');
});
test('protocol-less works', async t => {
const url = format('unix:%s:%s', socketPath, '/');
t.is((await got(url)).body, 'ok');
});

test('address with : works', async t => {
const url = format('unix:%s:%s', socketPath, '/foo:bar');
t.is((await got(url)).body, 'ok');
});
test('address with : works', async t => {
const url = format('unix:%s:%s', socketPath, '/foo:bar');
t.is((await got(url)).body, 'ok');
});

test.after('cleanup', async () => {
await s.close();
});
test.after('cleanup', async () => {
await s.close();
});
}

0 comments on commit 8afbe4e

Please sign in to comment.