1// Flags: --expose-internals 2'use strict'; 3const common = require('../common'); 4const assert = require('assert'); 5const dgram = require('dgram'); 6const dns = require('dns'); 7const { kStateSymbol } = require('internal/dgram'); 8 9// Monkey patch dns.lookup() so that it always fails. 10dns.lookup = function(address, family, callback) { 11 process.nextTick(() => { callback(new Error('fake DNS')); }); 12}; 13 14const socket = dgram.createSocket('udp4'); 15let dnsFailures = 0; 16let sendFailures = 0; 17 18process.on('exit', () => { 19 assert.strictEqual(dnsFailures, 3); 20 assert.strictEqual(sendFailures, 3); 21}); 22 23socket.on('error', (err) => { 24 if (/^Error: fake DNS$/.test(err)) { 25 // The DNS lookup should fail since it is monkey patched. At that point in 26 // time, the send queue should be populated with the send() operation. There 27 // should also be two listeners - this function and the dgram internal one 28 // time error handler. 29 dnsFailures++; 30 assert(Array.isArray(socket[kStateSymbol].queue)); 31 assert.strictEqual(socket[kStateSymbol].queue.length, 1); 32 assert.strictEqual(socket.listenerCount('error'), 2); 33 return; 34 } 35 36 if (err.code === 'ERR_SOCKET_CANNOT_SEND') { 37 // On error, the queue should be destroyed and this function should be 38 // the only listener. 39 sendFailures++; 40 assert.strictEqual(socket[kStateSymbol].queue, undefined); 41 assert.strictEqual(socket.listenerCount('error'), 1); 42 return; 43 } 44 45 assert.fail(`Unexpected error: ${err}`); 46}); 47 48// Initiate a few send() operations, which will fail. 49socket.send('foobar', common.PORT, 'localhost'); 50 51process.nextTick(() => { 52 socket.send('foobar', common.PORT, 'localhost'); 53}); 54 55setImmediate(() => { 56 socket.send('foobar', common.PORT, 'localhost'); 57}); 58