Skip to content
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

TCP socket emits error after close #35313

Open
tufosa opened this issue Sep 23, 2020 · 8 comments
Open

TCP socket emits error after close #35313

tufosa opened this issue Sep 23, 2020 · 8 comments
Labels
net Issues and PRs related to the net subsystem.

Comments

@tufosa
Copy link

tufosa commented Sep 23, 2020

What steps will reproduce the bug?

This might not be a bug itself, but just some missing details in the documentation. The documentation about TCP sockets claim 2 things:

  1. No more events are emitted after a close event (this is claimed in Writable streams)
  2. A close event is always emitted after an error event (this is claimed in net.Socket

There seems to be an edge case (writing into the socket after the close event) where both claims fail. To reproduce it, you will need to:

  1. Start a listener: node listener.js
// listener.js code
const net = require('net');                                
                                    
const server = net.createServer();                                
                                                
server.on('connection', socket => {                                 
  console.info('NEW SOCKET');                                
  socket.setEncoding('utf8');                                
  socket.on('data', data => console.info('DATA: ', data));                      
  socket.on('end', () => console.info('END'));                   
  socket.on('close', () => console.log('CLOSE'));                             
  socket.on('error', err => console.log('ERROR: ', err));                       
});                                                              
                                                                                
server.listen({host: '127.0.0.1', port: 1100});
  1. Start a sender: node sender.js
// sender.js code
const net = require('net');                                                                                                              
                                                                                
const socket = net.createConnection({host: '127.0.0.1', port: 1100});                                                                       
                                                            
socket.on('end', () => console.info('END'));                                    
socket.on('close', () => {                                                  
  console.info('CLOSE');
  socket.write('SOCKET CLOSE');
});                                                                             
socket.on('error', err => console.log('ERROR: ', err));
  1. Kill (ctrl+c) the listener process.
  2. Check that the CLOSE trace was written before the ERROR trace in the sender console.

I understand that you are not supposed to write in a socket after having received the close event, so this behavior might not be a bug, but it might require some changes in the docs.

I came across this behavior because it happened in one of our node.js applications in production and I was assuming in my code that error events could never come after close events. Of course, the real case was not as obvious as the example provided, and it was way trickier.

@watilde watilde added the net Issues and PRs related to the net subsystem. label Sep 26, 2020
@mmomtchev
Copy link
Contributor

write() to an already closed socket results in SIGPIPE (or it returns EPIPE if the SIGPIPE is explicitly ignored by the process - which Node does), so this behavior is consistent with the traditional BSD sockets behavior

@ronag
Copy link
Member

ronag commented Oct 13, 2020

Is this still a problem in v14? We did a lot of fixes related to this kind of things.

@tufosa
Copy link
Author

tufosa commented Oct 15, 2020

@mmomtchev that's why I suggest that this issue might not be a bug, but some missing details in the documentation. The docs claim 2 things (see the description of the issue) and none of them is fulfilled in this example.

@ronag I've just performed the experiment using node v14.13.1 and the results seem to be the same

@mmomtchev
Copy link
Contributor

@ronag This is the second similar question that I see, what should be the correct behavior of Node in this case? Is Node supposed to completely mask ECONNRESET and EPIPE from the user code?

@ronag
Copy link
Member

ronag commented Oct 20, 2020

'error' should not be emitted after 'close'.

@mmomtchev
Copy link
Contributor

So write after 'close' should be ignored silently?

@ronag
Copy link
Member

ronag commented Oct 20, 2020

So write after 'close' should be ignored silently?

The callback would still provide an error, but yes, no errors should be emitted.

@mmomtchev
Copy link
Contributor

There's no 'error' event on master, but there is on 12.x and 14.x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
net Issues and PRs related to the net subsystem.
Projects
None yet
Development

No branches or pull requests

4 participants