diff options
author | James M Snell <jasnell@gmail.com> | 2020-07-08 21:18:25 +0300 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2020-07-10 23:51:13 +0300 |
commit | 5e769b2eaf4595e9c8c429c8ae9bb4b32e6a7c8f (patch) | |
tree | f3eab5aaf3b21792a03016ca1d39df963a632113 /lib/internal/quic | |
parent | d36e832a32dfb0c0c49bf9e3dee93ff231c97eb0 (diff) |
quic: use less specific error codes
Stop the madness. Only you can prevent excessive error code
proliferation.
PR-URL: https://github.com/nodejs/node/pull/34262
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'lib/internal/quic')
-rw-r--r-- | lib/internal/quic/core.js | 158 | ||||
-rw-r--r-- | lib/internal/quic/util.js | 18 |
2 files changed, 101 insertions, 75 deletions
diff --git a/lib/internal/quic/core.js b/lib/internal/quic/core.js index 9b3d0f85da4..cca9c6f64a4 100644 --- a/lib/internal/quic/core.js +++ b/lib/internal/quic/core.js @@ -99,17 +99,9 @@ const { codes: { ERR_INVALID_ARG_TYPE, ERR_INVALID_CALLBACK, - ERR_QUICSESSION_DESTROYED, + ERR_INVALID_STATE, + ERR_OPERATION_FAILED, ERR_QUICSESSION_VERSION_NEGOTIATION, - ERR_QUICSOCKET_DESTROYED, - ERR_QUICSOCKET_LISTENING, - ERR_QUICCLIENTSESSION_FAILED, - ERR_QUICCLIENTSESSION_FAILED_SETSOCKET, - ERR_QUICSESSION_UPDATEKEY, - ERR_QUICSTREAM_DESTROYED, - ERR_QUICSTREAM_INVALID_PUSH, - ERR_QUICSTREAM_UNSUPPORTED_PUSH, - ERR_QUICSTREAM_OPEN_FAILED, ERR_TLS_DH_PARAM_SIZE, }, errnoException, @@ -761,79 +753,79 @@ class QuicEndpoint { setTTL(ttl) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('setTTL'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.setTTL(ttl); return this; } setMulticastTTL(ttl) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('setMulticastTTL'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.setMulticastTTL(ttl); return this; } setBroadcast(on = true) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('setBroadcast'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.setBroadcast(on); return this; } setMulticastLoopback(on = true) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('setMulticastLoopback'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.setMulticastLoopback(on); return this; } setMulticastInterface(iface) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('setMulticastInterface'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.setMulticastInterface(iface); return this; } addMembership(address, iface) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('addMembership'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.addMembership(address, iface); return this; } dropMembership(address, iface) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('dropMembership'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.dropMembership(address, iface); return this; } ref() { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('ref'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.ref(); return this; } unref() { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('unref'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicEndpoint is already destroyed'); state.udpSocket.unref(); return this; } destroy(error) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) + if (this.destroyed) return; state.state = kSocketDestroyed; this[kDestroy](error); @@ -1095,8 +1087,8 @@ class QuicSocket extends EventEmitter { addEndpoint(options = {}) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('listen'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); // TODO(@jasnell): Also forbid adding an endpoint if // the QuicSocket is closing. @@ -1224,12 +1216,12 @@ class QuicSocket extends EventEmitter { // function. listen(options, callback) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed || - state.state === kSocketClosing) { - throw new ERR_QUICSOCKET_DESTROYED('listen'); - } + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); + if (this.closing) + throw new ERR_INVALID_STATE('QuicSocket is closing'); if (this.listening || state.listenPending) - throw new ERR_QUICSOCKET_LISTENING(); + throw new ERR_INVALID_STATE('QuicSocket is already listening'); if (typeof options === 'function') { callback = options; options = {}; @@ -1300,8 +1292,10 @@ class QuicSocket extends EventEmitter { // Creates and returns a new QuicClientSession. connect(options, callback) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed || state.state === kSocketClosing) - throw new ERR_QUICSOCKET_DESTROYED('connect'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); + if (this.closing) + throw new ERR_INVALID_STATE('QuicSocket is closing'); if (typeof options === 'function') { callback = options; @@ -1364,8 +1358,8 @@ class QuicSocket extends EventEmitter { // immediately. close(callback) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('close'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); // If a callback function is specified, it is registered as a // handler for the once('close') event. If the close occurs @@ -1452,8 +1446,8 @@ class QuicSocket extends EventEmitter { ref() { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('ref'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); for (const endpoint of state.endpoints) endpoint.ref(); return this; @@ -1461,8 +1455,8 @@ class QuicSocket extends EventEmitter { unref() { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('unref'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); for (const endpoint of state.endpoints) endpoint.unref(); return this; @@ -1510,8 +1504,8 @@ class QuicSocket extends EventEmitter { // connection attempts to fail with a SERVER_BUSY CONNECTION_CLOSE. set serverBusy(on) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('serverBusy'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); validateBoolean(on, 'on'); if (state.sharedState.serverBusy !== on) { state.sharedState.serverBusy = on; @@ -1525,8 +1519,8 @@ class QuicSocket extends EventEmitter { set statelessResetDisabled(on) { const state = this[kInternalState]; - if (state.state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('statelessResetDisabled'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); validateBoolean(on, 'on'); if (state.sharedState.statelessResetDisabled !== on) state.sharedState.statelessResetDisabled = on; @@ -1598,8 +1592,8 @@ class QuicSocket extends EventEmitter { // option is a number between 0 and 1 that identifies the possibility of // packet loss in the given direction. setDiagnosticPacketLoss(options) { - if (this[kInternalState].state === kSocketDestroyed) - throw new ERR_QUICSOCKET_DESTROYED('setDiagnosticPacketLoss'); + if (this.destroyed) + throw new ERR_INVALID_STATE('QuicSocket is already destroyed'); const { rx = 0.0, tx = 0.0 @@ -1864,8 +1858,10 @@ class QuicSession extends EventEmitter { // fail, and new streams from the peer will be rejected/ignored. close(callback) { const state = this[kInternalState]; - if (state.destroyed) - throw new ERR_QUICSESSION_DESTROYED('close'); + if (state.destroyed) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is already destroyed`); + } if (callback) { if (typeof callback !== 'function') @@ -2048,8 +2044,10 @@ class QuicSession extends EventEmitter { } ping() { - if (!this[kHandle]) - throw new ERR_QUICSESSION_DESTROYED('ping'); + if (this.destroyed) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is already destroyed`); + } this[kHandle].ping(); } @@ -2084,8 +2082,14 @@ class QuicSession extends EventEmitter { openStream(options) { const state = this[kInternalState]; - if (state.destroyed || state.closing) - throw new ERR_QUICSESSION_DESTROYED('openStream'); + if (state.destroyed) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is already destroyed`); + } + if (state.closing) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is closing`); + } const { halfOpen, // Unidirectional or Bidirectional highWaterMark, @@ -2134,7 +2138,7 @@ class QuicSession extends EventEmitter { _openBidirectionalStream(this[kHandle]); if (handle === undefined) { - stream.destroy(new ERR_QUICSTREAM_OPEN_FAILED()); + stream.destroy(new ERR_OPERATION_FAILED('Unable to create QuicStream')); return; } @@ -2210,10 +2214,16 @@ class QuicSession extends EventEmitter { updateKey() { const state = this[kInternalState]; // Initiates a key update for the connection. - if (state.destroyed || state.closing) - throw new ERR_QUICSESSION_DESTROYED('updateKey'); + if (state.destroyed) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is already destroyed`); + } + if (state.closing) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is closing`); + } if (!state.handshakeConfirmed) - throw new ERR_QUICSESSION_UPDATEKEY(); + throw new ERR_INVALID_STATE('Handshake is not yet confirmed'); return this[kHandle].updateKey(); } @@ -2451,7 +2461,7 @@ class QuicClientSession extends QuicSession { default: reason = `${handle}`; } - this.destroy(new ERR_QUICCLIENTSESSION_FAILED(reason)); + this.destroy(new ERR_OPERATION_FAILED(reason)); return; } @@ -2501,8 +2511,10 @@ class QuicClientSession extends QuicSession { startHandshake() { const state = this[kInternalClientState]; - if (this.destroyed) - throw new ERR_QUICSESSION_DESTROYED('startHandshake'); + if (this.destroyed) { + throw new ERR_INVALID_STATE( + `${this.constructor.name} is already destroyed`); + } if (state.handshakeStarted) return; state.handshakeStarted = true; @@ -2521,12 +2533,12 @@ class QuicClientSession extends QuicSession { [kSetSocketAfterBind](socket, callback) { if (socket.destroyed) { - callback(new ERR_QUICSOCKET_DESTROYED('setSocket')); + callback(new ERR_INVALID_STATE('QuicSocket is already destroyed')); return; } if (!this[kHandle].setSocket(socket[kHandle])) { - callback(new ERR_QUICCLIENTSESSION_FAILED_SETSOCKET()); + callback(new ERR_OPERATION_FAILED('Could not set the QuicSocket')); return; } @@ -2982,7 +2994,7 @@ class QuicStream extends Duplex { pushStream(headers = {}, options = {}) { if (this.destroyed) - throw new ERR_QUICSTREAM_DESTROYED('push'); + throw new ERR_INVALID_STATE('QuicStream is already destroyed'); const state = this[kInternalState]; const { @@ -2999,8 +3011,11 @@ class QuicStream extends Duplex { // QUIC application protocol that has a similar // notion of push streams without this restriction, // then we'll need to check alpn value here also. - if (!this.clientInitiated && !this.bidirectional) - throw new ERR_QUICSTREAM_INVALID_PUSH(); + if (!this.clientInitiated && !this.bidirectional) { + throw new ERR_INVALID_STATE( + 'Push streams are only supported on client-initiated, ' + + 'bidirectional streams'); + } // TODO(@jasnell): The assertValidPseudoHeader validator // here is HTTP/3 specific. If we end up with another @@ -3015,8 +3030,11 @@ class QuicStream extends Duplex { // or push streams are currently disabled/blocked. This // will typically be the case with HTTP/3 when the client // peer has disabled push. - if (handle === undefined) - throw new ERR_QUICSTREAM_UNSUPPORTED_PUSH(); + if (handle === undefined) { + throw new ERR_INVALID_STATE( + 'Push stream could not be opened on this QuicSession. ' + + 'Push is either disabled or currently blocked.'); + } const stream = new QuicStream({ readable: false, diff --git a/lib/internal/quic/util.js b/lib/internal/quic/util.js index aff4f3cbc86..31087ef96e5 100644 --- a/lib/internal/quic/util.js +++ b/lib/internal/quic/util.js @@ -12,8 +12,6 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_OUT_OF_RANGE, - ERR_QUICSESSION_INVALID_DCID, - ERR_QUICSOCKET_INVALID_STATELESS_RESET_SECRET_LENGTH, }, } = require('internal/errors'); @@ -409,7 +407,10 @@ function validateQuicClientSessionOptions(options = {}) { try { dcid = Buffer.from(dcid_value, 'hex'); } catch { - throw new ERR_QUICSESSION_INVALID_DCID(dcid); + throw new ERR_INVALID_ARG_VALUE( + 'options.dcid', + dcid, + 'is not a valid QUIC connection ID'); } } @@ -420,7 +421,11 @@ function validateQuicClientSessionOptions(options = {}) { if (dcid_value.length > NGTCP2_MAX_CIDLEN || dcid_value.length < NGTCP2_MIN_CIDLEN) { - throw new ERR_QUICSESSION_INVALID_DCID(dcid_value.toString('hex')); + throw new ERR_INVALID_ARG_VALUE( + 'options.dcid', + dcid_value.toString('hex'), + 'is not a valid QUIC connection ID' + ); } dcid = dcid_value; @@ -575,7 +580,10 @@ function validateQuicSocketOptions(options = {}) { if (statelessResetSecret !== undefined) { validateBuffer(statelessResetSecret, 'options.statelessResetSecret'); if (statelessResetSecret.length !== 16) - throw new ERR_QUICSOCKET_INVALID_STATELESS_RESET_SECRET_LENGTH(); + throw new ERR_INVALID_ARG_VALUE( + 'options.statelessResetSecret', + statelessResetSecret, + 'must be exactly 16 bytes in length'); } return { |