socket.write() emits error synchronously when socket was closed by peer · Issue #24111 · nodejs/node (original) (raw)

var net = require('net')

var s = net.createServer().listen(0).on('listening', function() { var port = this.address().port; var c = net.connect(port).on('connect', function() { setTimeout(function() { var er; c.on('error', function(e) { er = e; console.log('on er', e); }); c.write('helo'); console.log('after write', er); }, 5); }); });

s.on('connection', function(c) { c.end(); });

EDIT: forgot output:

core/node (master % u=) % ./node ../sync-error.js
on er { Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (net.js:407:12)
    at Timeout._onTimeout (/home/sam/w/core/sync-error.js:12:9)
    at listOnTimeout (timers.js:324:15)
    at processTimers (timers.js:268:5) code: 'EPIPE' }
after write { Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (net.js:407:12)
    at Timeout._onTimeout (/home/sam/w/core/sync-error.js:12:9)
    at listOnTimeout (timers.js:324:15)
    at processTimers (timers.js:268:5) code: 'EPIPE' }

I would expect error to be emitted in the next tick, as it normally would for a runtime error. This matters because normally code like this would work:

sock,write(...) sock.on('error', ...)

but in the case of a TCP close by the peer, the error event will never be caught in the above.

I think the TODO in the source is referring to this:

// TODO: defer error events consistently everywhere, not just the cb

@mcollina what do you think? Is how net sockets are working here how a write stream is expected to work?