-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No end event is emitted when aborting http/https request #31630
Comments
@jasnell Thank you for quick reply. Is there any way other than At least, replacing setTimeout(() => {
console.log('abort');
- req.abort();
+ res.destroy();
}, 500); Changing like below may solve: .on('aborted', () => console.log('aborted'))
+ .on('aborted', () => res.readableEnded || res.emit('end'))
.on('error', (err) => console.log(err)); but causes an issue in v12: $ docker run --rm -it -v $(pwd)/test.js:/test.js node:12-buster-slim test.js
abort
aborted
end
end
close |
The change is deliberate, because @masnagam from your comment it is not clear what problem this change causes. |
@mcollina Thank you for you comment. That's ok to me if it's intentional. In Node.js v12, the end event is always emitted. So, I used it for detecting the end of the response stream. But, maybe, it's not correct way. I guess that we should use the |
If you are interested in knowing about both successful and aborted requests, you should use |
Now, I'm investigating a case of If |
Can you please post a full example to reproduce your problem? |
This change might cause problem when piping. I modified my test program like below: // test.js
const https = require('https');
const { Transform } = require('stream');
class MyTransform extends Transform {
constructor(options) {
super(options);
}
_transform(chunk, encoding, callback) {
callback();
}
_flush(callback) {
console.log('flush');
callback();
}
}
const req = https.request('https://nodejs.org/dist/v13.7.0/node-v13.7.0.tar.gz');
req.on('response', (res) => {
res
.on('end', () => console.log('end'))
.on('close', () => console.log('close'))
.on('aborted', () => console.log('aborted'))
.on('error', (err) => console.log(err));
res.pipe(new MyTransform);
setTimeout(() => {
console.log('abort');
req.abort();
}, 500);
});
req.end(); In Node.js v13, $ docker run --rm -it -v $(pwd)/test.js:/test.js node:13-buster-slim test.js
abort
aborted
close
$ docker run --rm -it -v $(pwd)/test.js:/test.js node:12-buster-slim test.js
abort
aborted
end
flush
close After changing like below: .on('aborted', () => console.log('aborted'))
+ .on('aborted', () => res.readableEnded || res.emit('end'))
.on('error', (err) => console.log(err)); $ docker run --rm -it -v $(pwd)/test.js:/test.js node:13-buster-slim test.js
abort
aborted
end
flush
close |
That is normal. Note that there are a few other cases where your stream would not terminate properly (as an example, in case of network errors). The "proper" behavior for streams in that case is that it should not call Use this: const https = require('https');
const { Transform, pipeline } = require('stream');
class MyTransform extends Transform {
constructor(options) {
super(options);
}
_transform(chunk, encoding, callback) {
callback();
}
_flush(callback) {
console.log('flush');
callback();
}
}
const req = https.request('https://nodejs.org/dist/v13.7.0/node-v13.7.0.tar.gz');
req.on('response', (res) => {
res
.on('end', () => console.log('end'))
.on('close', () => console.log('close'))
.on('aborted', () => console.log('aborted'))
.on('error', (err) => console.log(err));
pipeline(res, new MyTransform, function (err) {
if (err) { console.error(err) } // this will have an error, because it's an error situation.
});
setTimeout(() => {
console.log('abort');
req.abort();
}, 500);
});
req.end(); |
Thank you for your explanation! I fully understood my mistake. Thank you. |
I'm not sure if this is intended, but I found a difference between v12 and v13 regarding the
end
event.Node.js v12:
Node.js v13:
This issue might be related to:
The text was updated successfully, but these errors were encountered: