Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VBLOCKS-2054] Missing generated errors #192

Merged
merged 16 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
:warning: **Important**: If you are upgrading to version 2.3.0 or later and have firewall rules or network configuration that blocks any unknown traffic by default, you need to update your configuration to allow connections to the new DNS names and IP addresses. Please refer to this [changelog](#230-january-23-2023) for more details.

2.8.0 (In Progress)
===================

New Features
------------

- Added a new feature flag `enableImprovedSignalingErrorPrecision` to enhance the precision of errors emitted by `Device` and `Call` objects.

```ts
const token = ...;
const device = new Device(token, {
enableImprovedSignalingErrorPrecision: true,
});
```

The default value of this option is `false`.

When this flag is enabled, some errors that would have been described with a generic error code are now described with a more precise error code. With this feature, the following errors now have their own error codes. Please see this [page](https://www.twilio.com/docs/api/errors) for more details about each error.

- Device Error Changes

```ts
const device = new Device(token, {
enableImprovedSignalingErrorPrecision: true,
});
device.on('error', (deviceError) => {
// the following table describes how deviceError will change with this feature flag
});
```

| Device Error Name | Device Error Code with Feature Flag Enabled | Device Error Code with Feature Flag Disabled |
| --- | --- | --- |
| `GeneralErrors.ApplicationNotFoundError` | `31001` | `53000` |
| `GeneralErrors.ConnectionDeclinedError` | `31002` | `53000` |
| `GeneralErrors.ConnectionTimeoutError` | `31003` | `53000` |
| `MalformedRequestErrors.MissingParameterArrayError` | `31101` | `53000` |
| `MalformedRequestErrors.AuthorizationTokenMissingError` | `31102` | `53000` |
| `MalformedRequestErrors.MaxParameterLengthExceededError` | `31103` | `53000` |
| `MalformedRequestErrors.InvalidBridgeTokenError` | `31104` | `53000` |
| `MalformedRequestErrors.InvalidClientNameError` | `31105` | `53000` |
| `MalformedRequestErrors.ReconnectParameterInvalidError` | `31107` | `53000` |
| `SignatureValidationErrors.AccessTokenSignatureValidationFailed` | `31202` | `53000` |
| `AuthorizationErrors.NoValidAccountError` | `31203` | `53000` |
| `AuthorizationErrors.JWTTokenExpirationTooLongError` | `31207` | `53000` |
| `ClientErrors.NotFound` | `31404` | `53000` |
| `ClientErrors.TemporarilyUnavilable` | `31480` | `53000` |
| `ClientErrors.BusyHere` | `31486` | `53000` |
| `SIPServerErrors.Decline` | `31603` | `53000` |

- Call Error Changes

```ts
const device = new Device(token, {
enableImprovedSignalingErrorPrecision: true,
});
const call = device.connect(...);
call.on('error', (callError) => {
// the following table describes how callError will change with this feature flag
});
```

| Call Error Name | Call Error Code with Feature Flag Enabled | Call Error Code with Feature Flag Disabled |
| --- | --- | --- |
| `GeneralErrors.ConnectionDeclinedError` | `31002` | `31005` |
| `AuthorizationErrors.InvalidJWTTokenError` | `31204` | `31005` |
| `AuthorizationErrors.JWTTokenExpiredError` | `31205` | `31005` |

_**IMPORTANT:** If your application logic currently relies on listening to the generic error code `53000` or `31005`, and you opt into enabling the feature flag, then your applicaton logic needs to be updated to anticipate the new error code when any of the above errors happen._

2.7.2 (September 21, 2023)
=========================

Expand Down
15 changes: 14 additions & 1 deletion lib/twilio/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Device from './device';
import DialtonePlayer from './dialtonePlayer';
import {
GeneralErrors,
getPreciseSignalingErrorByCode,
InvalidArgumentError,
InvalidStateError,
MediaErrors,
Expand Down Expand Up @@ -247,6 +248,7 @@ class Call extends EventEmitter {
*/
private _options: Call.Options = {
MediaHandler: PeerConnection,
enableImprovedSignalingErrorPrecision: false,
offerSdp: null,
shouldPlayDisconnect: () => true,
voiceEventSidGenerator: generateVoiceEventSid,
Expand Down Expand Up @@ -1208,7 +1210,16 @@ class Call extends EventEmitter {

this._log.info('Received HANGUP from gateway');
if (payload.error) {
const error = new GeneralErrors.ConnectionError('Error sent from gateway in HANGUP');
const code = payload.error.code;
const errorConstructor = getPreciseSignalingErrorByCode(
this._options.enableImprovedSignalingErrorPrecision,
code,
);
const error = typeof errorConstructor !== 'undefined'
? new errorConstructor(payload.error.message)
: new GeneralErrors.ConnectionError(
'Error sent from gateway in HANGUP',
);
this._log.error('Received an error from the gateway:', error);
this.emit('error', error);
}
Expand Down Expand Up @@ -1877,6 +1888,8 @@ namespace Call {
*/
dscp?: boolean;

enableImprovedSignalingErrorPrecision: boolean;

/**
* Experimental feature.
* Force Chrome's ICE agent to use aggressive nomination when selecting a candidate pair.
Expand Down
109 changes: 95 additions & 14 deletions lib/twilio/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import {
AuthorizationErrors,
ClientErrors,
GeneralErrors,
getErrorByCode,
hasErrorByCode,
getPreciseSignalingErrorByCode,
InvalidArgumentError,
InvalidStateError,
NotSupportedError,
Expand Down Expand Up @@ -339,6 +338,7 @@ class Device extends EventEmitter {
closeProtection: false,
codecPreferences: [Call.Codec.PCMU, Call.Codec.Opus],
dscp: true,
enableImprovedSignalingErrorPrecision: false,
forceAggressiveIceNomination: false,
logLevel: LogLevels.ERROR,
maxCallSignalingTimeoutMs: 0,
Expand Down Expand Up @@ -554,10 +554,15 @@ class Device extends EventEmitter {
throw new InvalidStateError('A Call is already active');
}

const activeCall = this._activeCall = await this._makeCall(options.params || { }, {
rtcConfiguration: options.rtcConfiguration,
voiceEventSidGenerator: this._options.voiceEventSidGenerator,
});
const activeCall = this._activeCall = await this._makeCall(
options.params || { },
{
enableImprovedSignalingErrorPrecision:
!!this._options.enableImprovedSignalingErrorPrecision,
rtcConfiguration: options.rtcConfiguration,
voiceEventSidGenerator: this._options.voiceEventSidGenerator,
},
);

// Make sure any incoming calls are ignored
this._calls.splice(0).forEach(call => call.ignore());
Expand Down Expand Up @@ -1175,8 +1180,14 @@ class Device extends EventEmitter {
// Stop trying to register presence after token expires
this._stopRegistrationTimer();
twilioError = new AuthorizationErrors.AccessTokenExpired(originalError);
} else if (hasErrorByCode(code)) {
twilioError = new (getErrorByCode(code))(originalError);
} else {
const errorConstructor = getPreciseSignalingErrorByCode(
!!this._options.enableImprovedSignalingErrorPrecision,
code,
);
if (typeof errorConstructor !== 'undefined') {
twilioError = new errorConstructor(originalError);
}
}
}

Expand Down Expand Up @@ -1209,12 +1220,17 @@ class Device extends EventEmitter {

const customParameters = Object.assign({ }, queryToJson(callParameters.Params));

const call = await this._makeCall(customParameters, {
callParameters,
offerSdp: payload.sdp,
reconnectToken: payload.reconnect,
voiceEventSidGenerator: this._options.voiceEventSidGenerator,
});
const call = await this._makeCall(
customParameters,
{
callParameters,
enableImprovedSignalingErrorPrecision:
!!this._options.enableImprovedSignalingErrorPrecision,
offerSdp: payload.sdp,
reconnectToken: payload.reconnect,
voiceEventSidGenerator: this._options.voiceEventSidGenerator,
},
);

this._calls.push(call);

Expand Down Expand Up @@ -1717,6 +1733,71 @@ namespace Device {
*/
edge?: string[] | string;

/**
mhuynh5757 marked this conversation as resolved.
Show resolved Hide resolved
* Enhance the precision of errors emitted by `Device` and `Call` objects.
*
* The default value of this option is `false`.
*
* When this flag is enabled, some errors that would have been described
* with a generic error code, namely `53000` and `31005`, are now described
* with a more precise error code. With this feature, the following errors
* now have their own error codes. Please see this
* [page](https://www.twilio.com/docs/api/errors) for more details about
* each error.
*
* - Device Error Changes
*
* @example
* ```ts
* const device = new Device(token, {
* enableImprovedSignalingErrorPrecision: true,
* });
* device.on('error', (deviceError) => {
* // the following table describes how deviceError will change with this feature flag
* });
* ```
*
* | Device Error Name | Device Error Code with Feature Flag Enabled | Device Error Code with Feature Flag Disabled |
* | --- | --- | --- |
* | `GeneralErrors.ApplicationNotFoundError` | `31001` | `53000` |
* | `GeneralErrors.ConnectionDeclinedError` | `31002` | `53000` |
* | `GeneralErrors.ConnectionTimeoutError` | `31003` | `53000` |
* | `MalformedRequestErrors.MissingParameterArrayError` | `31101` | `53000` |
* | `MalformedRequestErrors.AuthorizationTokenMissingError` | `31102` | `53000` |
* | `MalformedRequestErrors.MaxParameterLengthExceededError` | `31103` | `53000` |
* | `MalformedRequestErrors.InvalidBridgeTokenError` | `31104` | `53000` |
* | `MalformedRequestErrors.InvalidClientNameError` | `31105` | `53000` |
* | `MalformedRequestErrors.ReconnectParameterInvalidError` | `31107` | `53000` |
* | `SignatureValidationErrors.AccessTokenSignatureValidationFailed` | `31202` | `53000` |
* | `AuthorizationErrors.NoValidAccountError` | `31203` | `53000` |
* | `AuthorizationErrors.JWTTokenExpirationTooLongError` | `31207` | `53000` |
* | `ClientErrors.NotFound` | `31404` | `53000` |
* | `ClientErrors.TemporarilyUnavilable` | `31480` | `53000` |
* | `ClientErrors.BusyHere` | `31486` | `53000` |
* | `SIPServerErrors.Decline` | `31603` | `53000` |
*
* - Call Error Changes
*
* @example
* ```ts
* const device = new Device(token, {
* enableImprovedSignalingErrorPrecision: true,
* });
* const call = device.connect(...);
* call.on('error', (callError) => {
* // the following table describes how callError will change with this feature flag
* });
* ```
*
* | Call Error Name | Call Error Code with Feature Flag Enabled | Call Error Code with Feature Flag Disabled |
* | --- | --- | --- |
* | `GeneralErrors.ConnectionDeclinedError` | `31002` | `31005` |
* | `AuthorizationErrors.InvalidJWTTokenError` | `31204` | `31005` |
* | `AuthorizationErrors.JWTTokenExpiredError` | `31205` | `31005` |
*
*/
enableImprovedSignalingErrorPrecision?: boolean;

/**
* Overrides the native MediaDevices.enumerateDevices API.
*/
Expand Down
Loading