Skip to content

http: emit ECONNRESET if no 'aborted' listener - #28677

Closed
ronag wants to merge 1 commit into
nodejs:masterfrom
nxtedition:fix-error-instead-of-aborted
Closed

http: emit ECONNRESET if no 'aborted' listener#28677
ronag wants to merge 1 commit into
nodejs:masterfrom
nxtedition:fix-error-instead-of-aborted

Conversation

@ronag

@ronagronag commented Jul 14, 2019

Copy link
Copy Markdown
Member

Emits an ECONNRESET of response object when there is no listener for aborted.

Refs: #28172

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@nodejs-github-botnodejs-github-bot added the http Issues or PRs related to the http subsystem. label Jul 14, 2019
@ronag
ronagforce-pushed the fix-error-instead-of-aborted branch 2 times, most recently from 8ce5c8d to 24f4a00CompareJuly 14, 2019 11:34
@mcollina

Copy link
Copy Markdown
Member

Would you mind adding a unit test?

@ronag
ronagforce-pushed the fix-error-instead-of-aborted branch from 24f4a00 to 0289de3CompareJuly 14, 2019 11:34
@ronag

Copy link
Copy Markdown
MemberAuthor

@mcollina@benjamingr docs and tests added

@ronagronag changed the title http: emit ECONNRESET if not aborted listenerhttp: emit ECONNRESET if no aborted listenerJul 14, 2019
@ronagronag changed the title http: emit ECONNRESET if no aborted listenerhttp: emit ECONNRESET if no 'aborted' listenerJul 14, 2019

@mcollinamcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ronag
ronagforce-pushed the fix-error-instead-of-aborted branch from 0289de3 to 37554a3CompareJuly 14, 2019 11:36
@mcollinamcollina added the semver-major PRs that contain breaking changes and should be released in the next major version. label Jul 14, 2019
@ronag

Copy link
Copy Markdown
MemberAuthor

@mcollina Thank you so much for the suggestion. This would make my life much easier.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

1 similar comment
@mcollina

Copy link
Copy Markdown
Member

@mcollinamcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ronag

Copy link
Copy Markdown
MemberAuthor

Hm, I have more tests to fix...

@ronag

Copy link
Copy Markdown
MemberAuthor

@mcollina May I deprecate/remove ‘aborted’ from the docs as well? Or is that a step too far?

@mcollina

Copy link
Copy Markdown
Member

I would not deprecate/remove at this point.

@lpinca

lpinca commented Jul 14, 2019

Copy link
Copy Markdown
Member

I think this is a pretty big breaking change as an 'error' listener should always be added on res now (if there is no 'aborted' listener) or the process will crash. It was sufficient to have an 'error' listener of req before.

@ronag

ronag commented Jul 14, 2019

Copy link
Copy Markdown
MemberAuthor

@lpinca not having an aborted listener on the response is currently quite a serious bug... and something I believe unfortunately is quite common. Currently it will fail silently.

From an API standpoint you should always have a error listener on the response object.

But yes, this could be a sem major?

@lpinca

Copy link
Copy Markdown
Member

not having an aborted listener on the response is currently quite a serious bug...

Why? care to elaborate?

Comment threadlib/_http_client.js Outdated
@ronag

ronag commented Jul 14, 2019

Copy link
Copy Markdown
MemberAuthor

not having an aborted listener on the response is currently quite a serious bug...

Why? care to elaborate?

Because you would never finish... consider the following quite common pattern:

awaitnewPromise((resolve,reject)=>res.on('error',reject).pipe(dst).on('error',reject).on('finish',resolve))

If 'aborted' this will never finish...

@mcollinamcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving it to “change requested” as we need a new error code for this.

@lpinca

Copy link
Copy Markdown
Member

Hmm unconvinced, the example above is a very specific use case and I'm not very happy with enforcing either an 'aborted' or an 'error' listener but I won't get in the way.

@ronag
ronagforce-pushed the fix-error-instead-of-aborted branch from 37554a3 to af06d83CompareJuly 14, 2019 15:21
@ronag

ronag commented Jul 14, 2019

Copy link
Copy Markdown
MemberAuthor

Hmm unconvinced, the example above is a very specific use case and I'm not very happy with enforcing either an 'aborted' or an 'error' listener but I won't get in the way.

Fair enough. The only other argument I can give is that it pretends to be a stream but doesn't follow the stream spec (if end is not emitted then error should be emitted).

@ronag
ronagforce-pushed the fix-error-instead-of-aborted branch from af06d83 to 147e7e2CompareJuly 14, 2019 15:29
@ronag

ronag commented Jul 14, 2019

Copy link
Copy Markdown
MemberAuthor

@mcollina: Tried a different message.

@mcollina

Copy link
Copy Markdown
Member

@lpinca what do you think?

@nodejs/tsc this is likely a significant breaking change, you might want to review again.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@mcollina

Copy link
Copy Markdown
Member

@lpinca

Copy link
Copy Markdown
Member

No strong opinion. The rationale seems sensible but I don't know if it makes sense due to the big breaking change.

@ronag

Copy link
Copy Markdown
MemberAuthor

@Trott: Is anything blocking this?

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@Trott

Copy link
Copy Markdown
Member

@TrottTrott added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. and removed author ready PRs that have at least one approval, no pending requests for changes, and a CI started. labels Sep 19, 2019
@Trott

Copy link
Copy Markdown
Member

With this change, CITGM has new failures for ws (7.1.2) and koa (2.8.1).

ws:

Details
2 failing 1) WebSocket Connection establishing "after each" hook: Uncaught Error: aborted at connResetException (internal/errors.js:566:14) at Socket.socketCloseListener (_http_client.js:364:27) at TCP.<anonymous> (net.js:658:12) 2) WebSocket Connection establishing "before each" hook for "connects when pathname is not null": TypeError: Cannot read property 'call' of undefined at processImmediate (internal/timers.js:439:21)

koa:

Details
3 failing 1) app.respond when ctx.respond === false should function (ctx): Error: aborted at connResetException (internal/errors.js:566:14) at Socket.socketCloseListener (_http_client.js:364:27) at TCP.<anonymous> (net.js:658:12) [use `--full-trace` to display the full stack trace] 2) app.respond when ctx.respond === false should ignore set header after header sent: Error: aborted at connResetException (internal/errors.js:566:14) at Socket.socketCloseListener (_http_client.js:364:27) at TCP.<anonymous> (net.js:658:12) [use `--full-trace` to display the full stack trace] 3) app.respond when ctx.respond === false should ignore set status after header sent: Error: aborted at connResetException (internal/errors.js:566:14) at Socket.socketCloseListener (_http_client.js:364:27) at TCP.<anonymous> (net.js:658:12) [use `--full-trace` to display the full stack trace] Error: mock stack null Error: ENOENT: no such file or directory, open 'does not exist' Error: ENOENT: no such file or directory, open 'does not exist' Error: ENOENT: no such file or directory, open 'does not exist' Error: ENOENT: no such file or directory, open 'does not exist' Error: ENOENT: no such file or directory, open 'does not exist' Error: boom!

@TrottTrott left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CITGM results would seem to indicate that we have some work to do in the ecosystem before landing this. If the approvers of this PR disagree and think it can/should land at this time, feel free to clear this review.

@ronag

ronag commented Sep 23, 2019

Copy link
Copy Markdown
MemberAuthor

@Trott:

@lpinca

Copy link
Copy Markdown
Member

Yes, I don't like it but I can live with it in ws. I'm actually more worried about similar breakage this can have on the ecosystem as per #28677 (comment).

I've seen a lot of code where no 'error' listener and no 'aborted' listener is added on the client side http.IncomingMessage because it just worked.

@ronag
ronag requested a review from TrottSeptember 23, 2019 13:34

@mcollinamcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering the breakage in the ecosystem, I don't think we should land this.

@ronag

ronag commented Sep 24, 2019

Copy link
Copy Markdown
MemberAuthor

because it just worked.

Or it just seems to work... I think a lot of the code that don't register error or aborted are already subtly broken... it's just such an unusual error case in those scenarios that it is not noticed. I don't have anything concrete to back that claim though.

@ronag

ronag commented Dec 15, 2019

Copy link
Copy Markdown
MemberAuthor

Considering the breakage in the ecosystem, I don't think we should land this.

I guess adding an option/flag to enable this behavior is not an option either? I find this whole 'aborted' thing very unfortunate when considering that we want the response to act like a stream. pipeline and finished does negate some of this though. However, I do see the breaking risks.

A process.'warning' if aborting and neither error nor aborted is registered?

@mcollina: Is there anything more that can be done here or should we close this?

@mcollina

Copy link
Copy Markdown
Member

I would close this for now, yes

@ronagronag closed this Dec 15, 2019
ronag added a commit that referenced this pull request May 10, 2020
Server requests aka. IncomingMessage emits 'aborted'
instead of 'error' which causes confusion when
the object is used as a regular stream, i.e. if
functions working on streams are passed a
server request object they might not work properly
unless they take this into account.
Refs: nodejs/web-server-frameworks#41
PR-URL: #33172Fixes: #28172
Refs: #28677
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

httpIssues or PRs related to the http subsystem.semver-majorPRs that contain breaking changes and should be released in the next major version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@ronag@mcollina@nodejs-github-bot@lpinca@benjamingr@Trott@jasnell