diff --git a/doc/api/errors.md b/doc/api/errors.md
index ebafd5a05fba54..40b8e7ab74cf71 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -703,6 +703,35 @@ in some cases may accept `func(undefined)` but not `func()`). In most native
Node.js APIs, `func(undefined)` and `func()` are treated identically, and the
[`ERR_INVALID_ARG_TYPE`][] error code may be used instead.
+
+### ERR_SOCKET_ALREADY_BOUND
+An error using the `'ERR_SOCKET_ALREADY_BOUND'` code is thrown when an attempt
+is made to bind a socket that has already been bound.
+
+
+### ERR_SOCKET_BAD_PORT
+
+An error using the `'ERR_SOCKET_BAD_PORT'` code is thrown when an API
+function expecting a port > 0 and < 65536 receives an invalid value.
+
+
+### ERR_SOCKET_BAD_TYPE
+
+An error using the `'ERR_SOCKET_BAD_TYPE'` code is thrown when an API
+function expecting a socket type (`udp4` or `udp6`) receives an invalid value.
+
+
+### ERR_SOCKET_CANNOT_SEND
+
+An error using the `'ERR_SOCKET_CANNOT_SEND'` code is thrown when data
+cannot be sent on a socket.
+
+
+### ERR_SOCKET_DGRAM_NOT_RUNNING
+
+An error using the `'ERR_SOCKET_DGRAM_NOT_RUNNING'` code is thrown
+when a call is made and the UDP subsystem is not running.
+
### ERR_STDERR_CLOSE
diff --git a/lib/dgram.js b/lib/dgram.js
index 4d9f7eb29fd97c..0d93ca28748e87 100644
--- a/lib/dgram.js
+++ b/lib/dgram.js
@@ -22,6 +22,7 @@
'use strict';
const assert = require('assert');
+const errors = require('internal/errors');
const Buffer = require('buffer').Buffer;
const util = require('util');
const EventEmitter = require('events');
@@ -78,7 +79,7 @@ function newHandle(type) {
return handle;
}
- throw new Error('Bad socket type specified. Valid types are: udp4, udp6');
+ throw new errors.Error('ERR_SOCKET_BAD_TYPE');
}
@@ -162,7 +163,7 @@ Socket.prototype.bind = function(port_, address_ /*, callback*/) {
this._healthCheck();
if (this._bindState !== BIND_STATE_UNBOUND)
- throw new Error('Socket is already bound');
+ throw new errors.Error('ERR_SOCKET_ALREADY_BOUND');
this._bindState = BIND_STATE_BINDING;
@@ -260,11 +261,21 @@ Socket.prototype.sendto = function(buffer,
port,
address,
callback) {
- if (typeof offset !== 'number' || typeof length !== 'number')
- throw new Error('Send takes "offset" and "length" as args 2 and 3');
+ if (typeof offset !== 'number') {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'offset', 'number');
+ }
+
+ if (typeof length !== 'number') {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'length', 'number');
+ }
- if (typeof address !== 'string')
- throw new Error(this.type + ' sockets must send to port, address');
+ if (typeof port !== 'number') {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'port', 'number');
+ }
+
+ if (typeof address !== 'string') {
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'address', 'string');
+ }
this.send(buffer, offset, length, port, address, callback);
};
@@ -274,8 +285,9 @@ function sliceBuffer(buffer, offset, length) {
if (typeof buffer === 'string') {
buffer = Buffer.from(buffer);
} else if (!isUint8Array(buffer)) {
- throw new TypeError('First argument must be a Buffer, ' +
- 'Uint8Array or string');
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
+ 'buffer',
+ ['Buffer', 'Uint8Array', 'string']);
}
offset = offset >>> 0;
@@ -323,7 +335,7 @@ function onListenSuccess() {
function onListenError(err) {
this.removeListener('listening', onListenSuccess);
this._queue = undefined;
- this.emit('error', new Error('Unable to send data'));
+ this.emit('error', new errors.Error('ERR_SOCKET_CANNOT_SEND'));
}
@@ -366,18 +378,21 @@ Socket.prototype.send = function(buffer,
if (typeof buffer === 'string') {
list = [ Buffer.from(buffer) ];
} else if (!isUint8Array(buffer)) {
- throw new TypeError('First argument must be a Buffer, ' +
- 'Uint8Array or string');
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
+ 'buffer',
+ ['Buffer', 'Uint8Array', 'string']);
} else {
list = [ buffer ];
}
} else if (!(list = fixBufferList(buffer))) {
- throw new TypeError('Buffer list arguments must be buffers or strings');
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
+ 'buffer list arguments',
+ ['Buffer', 'string']);
}
port = port >>> 0;
if (port === 0 || port > 65535)
- throw new RangeError('Port should be > 0 and < 65536');
+ throw new errors.RangeError('ERR_SOCKET_BAD_PORT');
// Normalize callback so it's either a function or undefined but not anything
// else.
@@ -388,8 +403,9 @@ Socket.prototype.send = function(buffer,
callback = address;
address = undefined;
} else if (address && typeof address !== 'string') {
- throw new TypeError('Invalid arguments: address must be a nonempty ' +
- 'string or falsy');
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
+ 'address',
+ ['string', 'falsy']);
}
this._healthCheck();
@@ -510,7 +526,9 @@ Socket.prototype.setBroadcast = function(arg) {
Socket.prototype.setTTL = function(arg) {
if (typeof arg !== 'number') {
- throw new TypeError('Argument must be a number');
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
+ 'arg',
+ 'number');
}
var err = this._handle.setTTL(arg);
@@ -524,7 +542,9 @@ Socket.prototype.setTTL = function(arg) {
Socket.prototype.setMulticastTTL = function(arg) {
if (typeof arg !== 'number') {
- throw new TypeError('Argument must be a number');
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
+ 'arg',
+ 'number');
}
var err = this._handle.setMulticastTTL(arg);
@@ -551,7 +571,7 @@ Socket.prototype.addMembership = function(multicastAddress,
this._healthCheck();
if (!multicastAddress) {
- throw new Error('multicast address must be specified');
+ throw new errors.TypeError('ERR_MISSING_ARGS', 'multicastAddress');
}
var err = this._handle.addMembership(multicastAddress, interfaceAddress);
@@ -566,7 +586,7 @@ Socket.prototype.dropMembership = function(multicastAddress,
this._healthCheck();
if (!multicastAddress) {
- throw new Error('multicast address must be specified');
+ throw new errors.TypeError('ERR_MISSING_ARGS', 'multicastAddress');
}
var err = this._handle.dropMembership(multicastAddress, interfaceAddress);
@@ -577,8 +597,10 @@ Socket.prototype.dropMembership = function(multicastAddress,
Socket.prototype._healthCheck = function() {
- if (!this._handle)
- throw new Error('Not running'); // error message from dgram_legacy.js
+ if (!this._handle) {
+ // Error message from dgram_legacy.js.
+ throw new errors.Error('ERR_SOCKET_DGRAM_NOT_RUNNING');
+ }
};
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 50d2c20325f0d6..1ca0f59d793b41 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -142,6 +142,12 @@ E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`);
E('ERR_UNKNOWN_SIGNAL', (signal) => `Unknown signal: ${signal}`);
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type');
+E('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound');
+E('ERR_SOCKET_BAD_TYPE',
+ 'Bad socket type specified. Valid types are: udp4, udp6');
+E('ERR_SOCKET_CANNOT_SEND', 'Unable to send data');
+E('ERR_SOCKET_BAD_PORT', 'Port should be > 0 and < 65536');
+E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running');
// Add new errors from here...
function invalidArgType(name, expected, actual) {
diff --git a/test/parallel/test-dgram-bind.js b/test/parallel/test-dgram-bind.js
index 25fd7408ffd17a..4e293a8021c160 100644
--- a/test/parallel/test-dgram-bind.js
+++ b/test/parallel/test-dgram-bind.js
@@ -29,7 +29,11 @@ const socket = dgram.createSocket('udp4');
socket.on('listening', common.mustCall(() => {
assert.throws(() => {
socket.bind();
- }, /^Error: Socket is already bound$/);
+ }, common.expectsError({
+ code: 'ERR_SOCKET_ALREADY_BOUND',
+ type: Error,
+ message: /^Socket is already bound$/
+ }));
socket.close();
}));
diff --git a/test/parallel/test-dgram-createSocket-type.js b/test/parallel/test-dgram-createSocket-type.js
index 1d269ddeda26eb..e6b17251f82060 100644
--- a/test/parallel/test-dgram-createSocket-type.js
+++ b/test/parallel/test-dgram-createSocket-type.js
@@ -1,5 +1,5 @@
'use strict';
-require('../common');
+const common = require('../common');
const assert = require('assert');
const dgram = require('dgram');
const invalidTypes = [
@@ -24,7 +24,11 @@ const validTypes = [
invalidTypes.forEach((invalidType) => {
assert.throws(() => {
dgram.createSocket(invalidType);
- }, /Bad socket type specified/);
+ }, common.expectsError({
+ code: 'ERR_SOCKET_BAD_TYPE',
+ type: Error,
+ message: /^Bad socket type specified\. Valid types are: udp4, udp6$/
+ }));
});
// Error must not be thrown with valid types
diff --git a/test/parallel/test-dgram-implicit-bind-failure.js b/test/parallel/test-dgram-implicit-bind-failure.js
index 626af418e533a9..2944c9aae72abe 100644
--- a/test/parallel/test-dgram-implicit-bind-failure.js
+++ b/test/parallel/test-dgram-implicit-bind-failure.js
@@ -31,7 +31,7 @@ socket.on('error', (err) => {
return;
}
- if (/^Error: Unable to send data$/.test(err)) {
+ if (err.code === 'ERR_SOCKET_CANNOT_SEND') {
// On error, the queue should be destroyed and this function should be
// the only listener.
sendFailures++;
diff --git a/test/parallel/test-dgram-membership.js b/test/parallel/test-dgram-membership.js
index 1543b9043f7738..586db5f3cfeb70 100644
--- a/test/parallel/test-dgram-membership.js
+++ b/test/parallel/test-dgram-membership.js
@@ -11,8 +11,13 @@ const setup = dgram.createSocket.bind(dgram, {type: 'udp4', reuseAddr: true});
{
const socket = setup();
socket.close(common.mustCall(() => {
- assert.throws(() => { socket.addMembership(multicastAddress); },
- /^Error: Not running$/);
+ assert.throws(() => {
+ socket.addMembership(multicastAddress);
+ }, common.expectsError({
+ code: 'ERR_SOCKET_DGRAM_NOT_RUNNING',
+ type: Error,
+ message: /^Not running$/
+ }));
}));
}
@@ -20,24 +25,39 @@ const setup = dgram.createSocket.bind(dgram, {type: 'udp4', reuseAddr: true});
{
const socket = setup();
socket.close(common.mustCall(() => {
- assert.throws(() => { socket.dropMembership(multicastAddress); },
- /^Error: Not running$/);
+ assert.throws(() => {
+ socket.dropMembership(multicastAddress);
+ }, common.expectsError({
+ code: 'ERR_SOCKET_DGRAM_NOT_RUNNING',
+ type: Error,
+ message: /^Not running$/
+ }));
}));
}
// addMembership() with no argument should throw
{
const socket = setup();
- assert.throws(() => { socket.addMembership(); },
- /^Error: multicast address must be specified$/);
+ assert.throws(() => {
+ socket.addMembership();
+ }, common.expectsError({
+ code: 'ERR_MISSING_ARGS',
+ type: TypeError,
+ message: /^The "multicastAddress" argument must be specified$/
+ }));
socket.close();
}
// dropMembership() with no argument should throw
{
const socket = setup();
- assert.throws(() => { socket.dropMembership(); },
- /^Error: multicast address must be specified$/);
+ assert.throws(() => {
+ socket.dropMembership();
+ }, common.expectsError({
+ code: 'ERR_MISSING_ARGS',
+ type: TypeError,
+ message: /^The "multicastAddress" argument must be specified$/
+ }));
socket.close();
}
diff --git a/test/parallel/test-dgram-multicast-setTTL.js b/test/parallel/test-dgram-multicast-setTTL.js
index 37a2d1586318ef..b7d1e01b321ac7 100644
--- a/test/parallel/test-dgram-multicast-setTTL.js
+++ b/test/parallel/test-dgram-multicast-setTTL.js
@@ -37,7 +37,11 @@ socket.on('listening', common.mustCall(() => {
assert.throws(() => {
socket.setMulticastTTL('foo');
- }, /^TypeError: Argument must be a number$/);
+ }, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: /^The "arg" argument must be of type number$/
+ }));
//close the socket
socket.close();
diff --git a/test/parallel/test-dgram-send-address-types.js b/test/parallel/test-dgram-send-address-types.js
index 6c5bf20e00db78..6b26c23a266558 100644
--- a/test/parallel/test-dgram-send-address-types.js
+++ b/test/parallel/test-dgram-send-address-types.js
@@ -10,8 +10,11 @@ const onMessage = common.mustCall((err, bytes) => {
assert.strictEqual(bytes, buf.length);
}, 6);
-const expectedError =
- /^TypeError: Invalid arguments: address must be a nonempty string or falsy$/;
+const expectedError = { code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message:
+ /^The "address" argument must be one of type string or falsy$/
+};
const client = dgram.createSocket('udp4').bind(0, () => {
const port = client.address().port;
@@ -37,17 +40,17 @@ const client = dgram.createSocket('udp4').bind(0, () => {
// invalid address: object
assert.throws(() => {
client.send(buf, port, []);
- }, expectedError);
+ }, common.expectsError(expectedError));
// invalid address: nonzero number
assert.throws(() => {
client.send(buf, port, 1);
- }, expectedError);
+ }, common.expectsError(expectedError));
// invalid address: true
assert.throws(() => {
client.send(buf, port, true);
- }, expectedError);
+ }, common.expectsError(expectedError));
});
client.unref();
diff --git a/test/parallel/test-dgram-sendto.js b/test/parallel/test-dgram-sendto.js
index 350f488f12af0d..c922dc1039e732 100644
--- a/test/parallel/test-dgram-sendto.js
+++ b/test/parallel/test-dgram-sendto.js
@@ -1,24 +1,48 @@
'use strict';
-require('../common');
+const common = require('../common');
const assert = require('assert');
const dgram = require('dgram');
const socket = dgram.createSocket('udp4');
-const errorMessage =
- /^Error: Send takes "offset" and "length" as args 2 and 3$/;
+const errorMessageOffset =
+ /^The "offset" argument must be of type number$/;
assert.throws(() => {
socket.sendto();
-}, errorMessage);
+}, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: errorMessageOffset
+}));
assert.throws(() => {
socket.sendto('buffer', 1, 'offset', 'port', 'address', 'cb');
-}, errorMessage);
+}, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: /^The "length" argument must be of type number$/
+}));
assert.throws(() => {
socket.sendto('buffer', 'offset', 1, 'port', 'address', 'cb');
-}, errorMessage);
+}, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: errorMessageOffset
+}));
assert.throws(() => {
socket.sendto('buffer', 1, 1, 10, false, 'cb');
-}, /^Error: udp4 sockets must send to port, address$/);
+}, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: /^The "address" argument must be of type string$/
+}));
+
+assert.throws(() => {
+ socket.sendto('buffer', 1, 1, false, 'address', 'cb');
+}, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: /^The "port" argument must be of type number$/
+}));
diff --git a/test/parallel/test-dgram-setTTL.js b/test/parallel/test-dgram-setTTL.js
index 7da3975ad4c3fd..c061fbc1870d9e 100644
--- a/test/parallel/test-dgram-setTTL.js
+++ b/test/parallel/test-dgram-setTTL.js
@@ -11,7 +11,11 @@ socket.on('listening', common.mustCall(() => {
assert.throws(() => {
socket.setTTL('foo');
- }, /^TypeError: Argument must be a number$/);
+ }, common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: /^The "arg" argument must be of type number$/
+ }));
// TTL must be a number from > 0 to < 256
assert.throws(() => {