diff --git a/lib/dgram.js b/lib/dgram.js index cb20c4499ad981..9cb304e51009a2 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -504,7 +504,7 @@ function onListenSuccess() { function onListenError(err) { this.removeListener('listening', onListenSuccess); this[kStateSymbol].queue = undefined; - this.emit('error', new ERR_SOCKET_CANNOT_SEND()); + this.emit('error', new ERR_SOCKET_CANNOT_SEND(err)); } diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 266358310bf3f7..50ab849da98891 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -610,6 +610,17 @@ function addNumericalSeparator(val) { return `${val.slice(0, i)}${res}`; } +// Append `causedByError` to the `error`. +function addCausedByError(error, message, causedByError) { + let msg = message; + if (causedByError) { + error.cause = causedByError; + if (typeof causedByError.message === 'string') + msg += ` (caused by: ${causedByError.message})`; + } + return msg; +} + module.exports = { addCodeToName, // Exported for NghttpError codes, @@ -802,13 +813,7 @@ E('ERR_HTTP2_STATUS_101', 'HTTP status code 101 (Switching Protocols) is forbidden in HTTP/2', Error); E('ERR_HTTP2_STATUS_INVALID', 'Invalid status code: %s', RangeError); E('ERR_HTTP2_STREAM_CANCEL', function(error) { - let msg = 'The pending stream has been canceled'; - if (error) { - this.cause = error; - if (typeof error.message === 'string') - msg += ` (caused by: ${error.message})`; - } - return msg; + return addCausedByError(this, 'The pending stream has been canceled', error); }, Error); E('ERR_HTTP2_STREAM_ERROR', 'Stream closed with error code %s', Error); E('ERR_HTTP2_STREAM_SELF_DEPENDENCY', @@ -1060,7 +1065,9 @@ E('ERR_SOCKET_BAD_TYPE', E('ERR_SOCKET_BUFFER_SIZE', 'Could not get or set buffer size', SystemError); -E('ERR_SOCKET_CANNOT_SEND', 'Unable to send data', Error); +E('ERR_SOCKET_CANNOT_SEND', function(error) { + return addCausedByError(this, 'Unable to send data', error); +}, Error); E('ERR_SOCKET_CLOSED', 'Socket is closed', Error); E('ERR_SOCKET_DGRAM_IS_CONNECTED', 'Already connected', Error); E('ERR_SOCKET_DGRAM_NOT_CONNECTED', 'Not connected', Error); diff --git a/test/sequential/test-dgram-implicit-bind-failure.js b/test/sequential/test-dgram-implicit-bind-failure.js index d77db12618f3bc..21779600faa9b7 100644 --- a/test/sequential/test-dgram-implicit-bind-failure.js +++ b/test/sequential/test-dgram-implicit-bind-failure.js @@ -21,7 +21,8 @@ process.on('exit', () => { }); socket.on('error', (err) => { - if (/^Error: fake DNS$/.test(err)) { + const fakeDNSReg = /^Error: fake DNS$/; + if (fakeDNSReg.test(err)) { // The DNS lookup should fail since it is monkey patched. At that point in // time, the send queue should be populated with the send() operation. There // should also be two listeners - this function and the dgram internal one @@ -39,6 +40,8 @@ socket.on('error', (err) => { sendFailures++; assert.strictEqual(socket[kStateSymbol].queue, undefined); assert.strictEqual(socket.listenerCount('error'), 1); + assert(err.cause instanceof Error); + assert(fakeDNSReg.test(err.cause)); return; }