Skip to content

'error' event no longer emitted for net connections #43724

@jonathansamines

Description

@jonathansamines

Version

16.15.1

Platform

Darwin LM-GUA-42000176 20.6.0 Darwin Kernel Version 20.6.0: Tue Apr 19 21:04:45 PDT 2022; root:xnu-7195.141.29~1/RELEASE_X86_64 x86_64

Subsystem

net

What steps will reproduce the bug?

'use strict';

const net = require('net');
const port = 4500;

const server = net.createServer((socket) => {
    socket.on('end', writeMessage);
    socket.end();
    server.close();
});

server.listen(port);

const socket = net.createConnection(port);

function writeMessage() {
    function logWriteError(err) {
        console.log('write cb error: ', err);
    }

    function logEventError(err) {
        console.log('event error: ', err);
    }

    socket.on('error', logEventError);
    socket.write('some message', 'utf8', logWriteError);
}

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior?

The 'error' event is emitted when .write() is called after a connection has been terminated by the server. This is how it used to work in Node 14:

event error:  Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (net.js:468:14)
    at Socket.writeMessage (/Users/jsamines/dev/personal/node-lazy-socket/test/integration/test-net-connect-close-errors.js:26:12)
    at Socket.emit (events.js:412:35)
    at endReadableNT (internal/streams/readable.js:1333:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  code: 'EPIPE'
}
write cb error:  Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (net.js:468:14)
    at Socket.writeMessage (/Users/jsamines/dev/personal/node-lazy-socket/test/integration/test-net-connect-close-errors.js:26:12)
    at Socket.emit (events.js:412:35)
    at endReadableNT (internal/streams/readable.js:1333:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  code: 'EPIPE'
}

What do you see instead?

The 'error' event is no longer emitted when .write() is called after a connection has been terminated by the server on Node 16:

write cb error:  Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (node:net:487:14)
    at Socket.writeMessage (/Users/jsamines/dev/personal/node-lazy-socket/test/integration/test-net-connect-close-errors.js:26:12)
    at Socket.emit (node:events:539:35)
    at endReadableNT (node:internal/streams/readable:1345:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  code: 'EPIPE'
}

Additional information

It might be an intentional breaking change introduced by #31806, though it is hard to tell if this specific change is intentional. The provided reproduction is as small as possible, but this change in behavior broke lazy-socket (See felixge/node-lazy-socket#3), which in turn broke the graphite library (See felixge/node-graphite#16).

Metadata

Metadata

Assignees

No one assigned

    Labels

    netIssues and PRs related to the net subsystem.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions