diff --git a/doc/api/dgram.markdown b/doc/api/dgram.markdown index 7c13d1746f7036..896bf90d30077a 100644 --- a/doc/api/dgram.markdown +++ b/doc/api/dgram.markdown @@ -114,7 +114,9 @@ assigned a random port number and is bound to the "all interfaces" address An optional callback may be specified to detect DNS errors or for determining when it's safe to reuse the `buf` object. Note that DNS lookups delay the time to send for at least one tick. The only way to know for sure that the datagram -has been sent is by using a callback. +has been sent is by using a callback. If an error occurs and a callback is given, +the error will be the first argument to the callback. If a callback is not given, +the error is emitted as an `'error'` event on the `socket` object. With consideration for multi-byte characters, `offset` and `length` will be calculated with respect to diff --git a/lib/dgram.js b/lib/dgram.js index f95b44926999cb..681de91d4e04b9 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -299,7 +299,11 @@ Socket.prototype.send = function(buffer, self._handle.lookup(address, function(ex, ip) { if (ex) { - if (callback) callback(ex); + if (typeof callback === 'function') { + callback(ex); + return; + } + self.emit('error', ex); } else if (self._handle) { var req = new SendWrap(); diff --git a/test/internet/test-dgram-send-cb-quelches-error.js b/test/internet/test-dgram-send-cb-quelches-error.js new file mode 100644 index 00000000000000..e89306b2c29aa2 --- /dev/null +++ b/test/internet/test-dgram-send-cb-quelches-error.js @@ -0,0 +1,37 @@ +'use strict'; +var common = require('../common'); +var mustCall = common.mustCall; +var assert = require('assert'); +var dgram = require('dgram'); +var dns = require('dns'); + +var socket = dgram.createSocket('udp4'); +var buffer = new Buffer('gary busey'); + +dns.setServers([]); + +socket.once('error', onEvent); + +// assert that: +// * callbacks act as "error" listeners if given. +// * error is never emitter for missing dns entries +// if a callback that handles error is present +// * error is emitted if a callback with no argument is passed +socket.send(buffer, 0, buffer.length, 100, + 'dne.example.com', mustCall(callbackOnly)); + +function callbackOnly(err) { + assert.ok(err); + socket.removeListener('error', onEvent); + socket.on('error', mustCall(onError)); + socket.send(buffer, 0, buffer.length, 100, 'dne.example.com'); +} + +function onEvent(err) { + assert.fail('Error should not be emitted if there is callback'); +} + +function onError(err) { + assert.ok(err); + socket.close(); +}