Skip to content

Instantly share code, notes, and snippets.

@davepacheco
Last active February 20, 2018 23:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davepacheco/2226f2bbe25e6227f4d7e08a18b288e2 to your computer and use it in GitHub Desktop.
Save davepacheco/2226f2bbe25e6227f4d7e08a18b288e2 to your computer and use it in GitHub Desktop.
This gist contains a test program and sample output that shows a case where a Node stream can see an "error" event after an "end" event. The results are the same across both illumos and Mac OS X, and for Node versions v0.10, v0.12, v4.4, and v5.9.
/*
* test-stream.js: demonstrates a case where a Node stream can see an 'error'
* event after an 'end' event. This example creates a server socket and then
* establishes a connection to it. If the client destroys the socket and the
* server keeps writing to it, it's possible for the server to see both an 'end'
* event and an 'error' event.
*/
var mod_net = require('net');
var mod_os = require('os');
/* IP address and port used for this test case. */
var ip = '127.0.0.1';
var port = 16404;
var server; /* server's listening socket */
var ssock; /* server's connection socket */
var csock; /* client socket */
var end = false, error = false;
function main()
{
console.log('versions:',
process.version, process.arch, mod_os.platform());
server = mod_net.createServer({ 'allowHalfOpen': true });
server.on('connection', function (s) {
console.log('server: client connected');
ssock = s;
ssock.on('data', function () {
console.log('server: saw "data" on client socket');
});
ssock.on('end', function () {
console.log('server: saw "end" on client socket');
if (error) {
console.log('reproduced issue!');
process.abort();
}
end = true;
});
ssock.on('error', function (err) {
console.log('server: saw "error" on client socket', err);
if (error || end) {
console.log('bailing out after server error');
process.exit(0);
}
error = true;
});
/*
* After a brief delay, trigger the issue.
*/
setTimeout(triggerIssue, 1000);
});
server.listen(port, function () {
console.log('server: listening');
csock = mod_net.createConnection(port, ip);
csock.on('connect', function () {
console.log('client: connected');
});
csock.on('data', function () {
console.log('client: saw "data" on server socket');
});
csock.on('end', function () {
console.log('client: saw "end" on server socket');
});
csock.on('error', function (err) {
console.log('client: saw "error" on server socket', err);
});
});
}
function triggerIssue()
{
console.log('triggering issue by destroying client socket');
csock.destroy();
setImmediate(writeLoop);
}
function writeLoop()
{
console.log('server: writing');
ssock.write('boom');
setImmediate(writeLoop);
}
main();
versions: v0.10.43 x64 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v0.10.43 ia32 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v0.12.12 x64 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v0.12.12 ia32 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v0.12.2 x64 darwin
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v4.4.0 x64 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v4.4.0 ia32 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v4.4.2 x64 darwin
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v5.10.0 x64 darwin
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v5.9.0 x64 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
versions: v5.9.0 ia32 sunos
server: listening
server: client connected
client: connected
triggering issue by destroying client socket
server: saw "end" on client socket
server: writing
server: writing
server: saw "error" on client socket { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
bailing out after server error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment