Add error event hander for the body stream even if the body isn't accessed (#379)
Fixes #378
This commit is contained in:
parent
a9c76c19ac
commit
19b115f9dc
12
src/body.js
12
src/body.js
|
@ -12,6 +12,7 @@ const Stream = require('stream');
|
|||
const { PassThrough } = require('stream');
|
||||
|
||||
const DISTURBED = Symbol('disturbed');
|
||||
const ERROR = Symbol('error');
|
||||
|
||||
let convert;
|
||||
try { convert = require('encoding').convert; } catch(e) {}
|
||||
|
@ -49,8 +50,15 @@ export default function Body(body, {
|
|||
}
|
||||
this.body = body;
|
||||
this[DISTURBED] = false;
|
||||
this[ERROR] = null;
|
||||
this.size = size;
|
||||
this.timeout = timeout;
|
||||
|
||||
if (this.body instanceof Stream) {
|
||||
this.body.on('error', err => {
|
||||
this[ERROR] = new FetchError(`Invalid response body while trying to fetch ${this.url}: ${err.message}`, 'system', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Body.prototype = {
|
||||
|
@ -153,6 +161,10 @@ function consumeBody(body) {
|
|||
|
||||
this[DISTURBED] = true;
|
||||
|
||||
if (this[ERROR]) {
|
||||
return Body.Promise.reject(this[ERROR]);
|
||||
}
|
||||
|
||||
// body is null
|
||||
if (this.body === null) {
|
||||
return Body.Promise.resolve(Buffer.alloc(0));
|
||||
|
|
34
test/test.js
34
test/test.js
|
@ -587,6 +587,40 @@ describe('node-fetch', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should handle errors on the body stream even if it is not used', function(done) {
|
||||
url = `${base}invalid-content-encoding`;
|
||||
fetch(url)
|
||||
.then(res => {
|
||||
expect(res.status).to.equal(200);
|
||||
})
|
||||
.catch(() => {})
|
||||
.then(() => {
|
||||
// Wait a few ms to see if a uncaught error occurs
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
it('should collect handled errors on the body stream to reject if the body is used later', function() {
|
||||
|
||||
function delay(value) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(value)
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
url = `${base}invalid-content-encoding`;
|
||||
return fetch(url).then(delay).then(res => {
|
||||
expect(res.headers.get('content-type')).to.equal('text/plain');
|
||||
return expect(res.text()).to.eventually.be.rejected
|
||||
.and.be.an.instanceOf(FetchError)
|
||||
.and.have.property('code', 'Z_DATA_ERROR');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow disabling auto decompression', function() {
|
||||
url = `${base}gzip`;
|
||||
opts = {
|
||||
|
|
Loading…
Reference in New Issue