Skip to content

Commit f343daa

Browse files
authored
fix: ignore request error if request is done (#384)
* ci: add request error after request finish case
1 parent 518d22c commit f343daa

File tree

4 files changed

+46
-23
lines changed

4 files changed

+46
-23
lines changed

.github/workflows/nodejs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
node-version: ${{ matrix.node-version }}
3636

3737
- name: Install Dependencies
38-
run: npm i -g npminstall && npminstall
38+
run: npm i -g npminstall@latest-5 && npminstall
3939

4040
- name: Continuous Integration
4141
run: npm run ci

lib/urllib.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,13 @@ function requestWithCallback(url, args, callback) {
728728
}
729729

730730
function decodeContent(res, body, cb) {
731+
if (responseAborted) {
732+
// err = new Error('Remote socket was terminated before `response.end()` was called');
733+
// err.name = 'RemoteSocketClosedError';
734+
debug('Request#%d %s: Remote socket was terminated before `response.end()` was called', reqId, url);
735+
var err = responseError || new Error('Remote socket was terminated before `response.end()` was called');
736+
return cb(err);
737+
}
731738
var encoding = res.headers['content-encoding'];
732739
if (body.length === 0 || !encoding) {
733740
return cb(null, body, encoding);
@@ -758,7 +765,10 @@ function requestWithCallback(url, args, callback) {
758765

759766
args.requestUrls.push(parsedUrl.href);
760767

768+
var hasResponse = false;
769+
var responseError;
761770
function onResponse(res) {
771+
hasResponse = true;
762772
socketHandledResponses = res.socket[SOCKET_RESPONSE_COUNT] = (res.socket[SOCKET_RESPONSE_COUNT] || 0) + 1;
763773
if (timing) {
764774
timing.waiting = Date.now() - requestStartTime;
@@ -781,7 +791,8 @@ function requestWithCallback(url, args, callback) {
781791
return done(null, null, res);
782792
}
783793

784-
res.on('error', function () {
794+
res.on('error', function (err) {
795+
responseError = err;
785796
debug('Request#%d %s: `res error` event emit, total size %d, socket handled %s requests and %s responses',
786797
reqId, url, responseSize, socketHandledRequests, socketHandledResponses);
787798
});
@@ -939,12 +950,6 @@ function requestWithCallback(url, args, callback) {
939950
}
940951
}
941952

942-
if (responseAborted) {
943-
// err = new Error('Remote socket was terminated before `response.end()` was called');
944-
// err.name = 'RemoteSocketClosedError';
945-
debug('Request#%d %s: Remote socket was terminated before `response.end()` was called', reqId, url);
946-
}
947-
948953
done(err, data, res);
949954
});
950955
}
@@ -1161,12 +1166,17 @@ function requestWithCallback(url, args, callback) {
11611166
});
11621167
}
11631168

1164-
var isRequestError = false;
1169+
var isRequestDone = false;
11651170
function handleRequestError(err) {
1166-
if (isRequestError || !err) {
1171+
if (!err) {
11671172
return;
11681173
}
1169-
isRequestError = true;
1174+
// only ignore request error if response has been received
1175+
// if response has not received, socket error will emit on req
1176+
if (isRequestDone && hasResponse) {
1177+
return;
1178+
}
1179+
isRequestDone = true;
11701180

11711181
if (err.name === 'Error') {
11721182
err.name = connected ? 'ResponseError' : 'RequestError';
@@ -1178,7 +1188,9 @@ function requestWithCallback(url, args, callback) {
11781188
debug('Request#%d pump args.stream to req', reqId);
11791189
pump(args.stream, req, handleRequestError);
11801190
} else {
1181-
req.end(body);
1191+
req.end(body, function () {
1192+
isRequestDone = true;
1193+
});
11821194
}
11831195
// when stream already consumed, req's `finish` event is emitted and pump will ignore error after pipe finished
11841196
// but if server response timeout later, we will abort the request and emit an error in req

test/proxy.test.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var proxy = require('./fixtures/reverse-proxy');
66
var isNode010 = /^v0\.10\.\d+$/.test(process.version);
77
var isNode012 = /^v0\.12\.\d+$/.test(process.version);
88

9-
var testUrl = process.env.CI ? 'https://registry.npmjs.com' : 'https://registry.npm.taobao.org';
9+
var testUrl = process.env.CI ? 'https://registry.npmjs.com' : 'https://registry.npmmirror.com';
1010

1111
if (!isNode010 && !isNode012) {
1212
describe('test/proxy.test.js', function() {
@@ -25,15 +25,12 @@ if (!isNode010 && !isNode012) {
2525
});
2626

2727
it('should proxy http work', function(done) {
28-
urllib.request('http://registry.npm.taobao.org/pedding/1.0.0', {
29-
dataType: 'json',
28+
urllib.request('http://registry.npmmirror.com/pedding/1.0.0', {
3029
enableProxy: true,
3130
proxy: proxyUrl,
3231
}, function(err, data, res) {
3332
assert(!err);
34-
console.log(res.headers);
35-
assert(data.name === 'pedding');
36-
assert(res.status === 200);
33+
assert(res.status === 301);
3734
done();
3835
});
3936
});

test/urllib.test.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,11 +411,8 @@ describe('test/urllib.test.js', function () {
411411
it('should handle server socket end("balabal") will error', function (done) {
412412
urllib.request(host + '/socket.end.error', function (err, data) {
413413
assert(err);
414-
assert(err.name === 'ResponseError');
415-
err.code && assert(err.code === 'HPE_INVALID_CHUNK_SIZE');
416-
assert(/Parse Error.*GET http:\/\/127\.0\.0\.1:/.test(err.message) >= 0);
417-
assert(err.bytesParsed === 2);
418-
assert(!data);
414+
err.code && assert(err.code === 'ECONNRESET');
415+
assert(data);
419416
done();
420417
});
421418
});
@@ -980,6 +977,23 @@ describe('test/urllib.test.js', function () {
980977
});
981978
});
982979
});
980+
981+
it('should not emit request error if request is done', function (done) {
982+
var req = urllib.request(host + '/stream', {
983+
method: 'post',
984+
data: {foo: 'bar'},
985+
ctx: {
986+
foo: 'stream request'
987+
}
988+
}, function (err) {
989+
assert(!err);
990+
done();
991+
});
992+
993+
req.on('response', () => {
994+
req.emit('error', new Error('mock error'));
995+
});
996+
});
983997
});
984998

985999
describe('support stream', function () {

0 commit comments

Comments
 (0)