-
-
Notifications
You must be signed in to change notification settings - Fork 42
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
response is only finished if socket is detached #31
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
If these are two different fixes, please split into two PRs. If not, then no problem. There is no description or tests so I'm not sure (a) if they are the just one fix or two separate fixes (b) what specifically they are fixing and (c) if they consistently fix the issue across the supported Node.js versions this module supports.
Sorry, fixed! |
This PR does make the situation better. But it does not fully solve the issue. If |
c5a5131
to
7c8d7f3
Compare
Ok, I think I've found a way that catches all edge cases and also doesn't break http/2 compat. |
The logic here is a bit complicated. We can't just rely on |
a20c73d
to
e73e839
Compare
index.js
Outdated
if (msg.stream) { | ||
// Http2ServerRequest | ||
// Http2ServerResponse | ||
return msg.stream.closed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note this is needed in order to not break http2 compat which does not implement outputSize
.
ec12f71
to
200fb77
Compare
Updated test |
Fails in node < 0.4. Is that a problem? |
Is there anything more I can do here? |
Hi @ronag . Sorry I have been out of a computer at the moment. This is a core piece of Express, and was created in support of the Express project. It looks like there are two core issues that block merging this currently: there is uncovered code in the PR (the coveralls check failure) and the failed CI on supported platforms (< 4, as you noted above). I may be able to help you get those two things fixed up, though, if you're not sure how. If you're stuck on getting the checks on the PR resolved, please let me know and I can lend a hand. |
The coveralls and node < 4 are a bit out of my expertise. |
It's no problem at all, I can help out. So for the coveralls, it would just indicate that it is unreached code, as in there is no tests added to cover the added branches/lines. I can help construct tests and add the < 4 support if you can help me understand the changes in this PR and/or how you've been manually testing the changes, which I can help replicate into automated tests. |
So the problem this is trying to fix is the fact that There is currently no easy way to query this information from the response object in the success scenario (
The logic here is a bit complicated. We can't just rely on I've updated the test to check that it is not finished after Furthermore, I had to add some extra code (hence the coveralls failure) to ensure we don't break node http/2 compat which does not have a I suspect node < 4 does not have |
Gotcha. So this module (in the 1.x form) does consider the response finished after |
Another way to phrase it. This PR fixes so that ‘isFinished’ is never true before ‘onFinished’ has been called. |
Well, more like this module's design was just to add a callback to the definition of what node.js http server considered finished, i.e. the And I'm not arguing otherwise, only noting that this is not a bug fix, because the module is operating exactly as intended. It can certainly be made to change this definition away from the node.js finished property as a new major iteration of this module if that is what is desired here. But in the same vein, it actually sounds like the bug is that the callback this module tried to add on top of the Remember: this module was built around adding a callback to the |
Anyway, regardless, I still want to help land this pull request, so maybe we should focus on the tasks at hand for that 👍 So I had originally saw your multiple commit iterations, and there is the http/2 issue. Were you testing the changes by hand? If so, can you help me replicate that setup? I can do the leg work to then translate into automated test cases in the test suite. |
I was just reviewing the code. I don't have a setup for h2. |
This is also relevant nodejs/node#28621 |
return ( | ||
msg.finished && | ||
msg.outputSize === 0 && | ||
(!socket || socket.writableLength === 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has landed in node 12 as writableFinished.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: writtableFinished
writableFinished
.
Hey @ronag! I am trying to do some house cleaning and just stumbled on this and #32. Can you help me come up to speed on this and decide on next steps?
At first I saw both of these as bug fixes, but this makes me question it. We can certainly major version rev this if necessary (and maybe should just to drop old node versions), but I think the main thing we want to ensure is that this behavior aligns with the tag line "Execute a callback when a HTTP request closes, finishes, or errors". I don't want to nit pick the original purpose of this package, only to resolve this so that it best serves the users of this (directly or via |
A quick question, the problem mentioned in #30, is this a correct reproduction? const express = require('express');
const onFinished = require('on-finished');
const app = express();
app.get('/', (req, res) => {
res.write('Initial data...\n');
// End the response
res.end('Response ended.\n');
// Simulate an error after the response is ended
setTimeout(() => {
res.emit('error', new Error('An error occurred after .end()'));
}, 1000);
onFinished(res, (err) => {
if (err) {
console.log('Error occurred after response ended:', err.message);
} else {
console.log('Response finished.');
}
});
});
app.listen(3000, () => {
console.log('App running on port 3000');
}); cc: @ronag @wesleytodd |
This is all from quite a long time ago. I think it is a reproduction, but without digging in again I don't want to say with certainty. I would look to you to prove this out if you would like to help land this. |
Refs: #30