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

fix: add trackType to track related errors #3350

Merged
merged 21 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
5 changes: 3 additions & 2 deletions packages/hms-video-store/src/device-manager/DeviceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DeviceMap, HMSDeviceChangeEvent, SelectedDevices } from '../interfaces'
import { getAudioDeviceCategory, HMSAudioDeviceCategory, isIOS } from '../internal';
import { HMSAudioTrackSettingsBuilder, HMSVideoTrackSettingsBuilder } from '../media/settings';
import { HMSLocalAudioTrack, HMSLocalTrack, HMSLocalVideoTrack } from '../media/tracks';
import { HMSTrackExceptionTrackType } from '../media/tracks/HMSTrackExceptionTrackType';
import { Store } from '../sdk/store';
import HMSLogger from '../utils/logger';
import { debounce } from '../utils/timer-utils';
Expand Down Expand Up @@ -325,7 +326,7 @@ export class DeviceManager implements HMSDeviceManager {
this.eventBus.analytics.publish(
AnalyticsEventFactory.deviceChange({
selection: { audioInput: newSelection },
error: ErrorFactory.TracksErrors.SelectedDeviceMissing('audio'),
error: ErrorFactory.TracksErrors.SelectedDeviceMissing(HMSTrackExceptionTrackType.AUDIO),
devices: this.getDevices(),
type: 'audioInput',
}),
Expand Down Expand Up @@ -383,7 +384,7 @@ export class DeviceManager implements HMSDeviceManager {
this.eventBus.analytics.publish(
AnalyticsEventFactory.deviceChange({
selection: { videoInput: newSelection },
error: ErrorFactory.TracksErrors.SelectedDeviceMissing('video'),
error: ErrorFactory.TracksErrors.SelectedDeviceMissing(HMSTrackExceptionTrackType.VIDEO),
devices: this.getDevices(),
type: 'video',
}),
Expand Down
52 changes: 34 additions & 18 deletions packages/hms-video-store/src/error/ErrorFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import { ErrorCodes } from './ErrorCodes';
import { HMSAction } from './HMSAction';
import { HMSException } from './HMSException';
import { HMSTrackException } from './HMSTrackException';
import { HMSTrackExceptionTrackType } from '../media/tracks/HMSTrackExceptionTrackType';
import { HMSSignalMethod } from '../signal/jsonrpc/models';

const terminalActions: (HMSSignalMethod | HMSAction)[] = [
Expand Down Expand Up @@ -98,52 +100,56 @@ export const ErrorFactory = {

TracksErrors: {
GenericTrack(action: HMSAction, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.GENERIC_TRACK,
'GenericTrack',
action,
`[TRACK]: ${description}`,
`[TRACK]: ${description}`,
HMSTrackExceptionTrackType.AUDIO_VIDEO,
);
},

CantAccessCaptureDevice(action: HMSAction, deviceInfo: string, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.CANT_ACCESS_CAPTURE_DEVICE,
'CantAccessCaptureDevice',
action,
`User denied permission to access capture device - ${deviceInfo}`,
description,
deviceInfo as HMSTrackExceptionTrackType,
);
},

DeviceNotAvailable(action: HMSAction, deviceInfo: string, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.DEVICE_NOT_AVAILABLE,
'DeviceNotAvailable',
action,
`[TRACK]: Capture device is no longer available - ${deviceInfo}`,
description,
deviceInfo as HMSTrackExceptionTrackType,
);
},

DeviceInUse(action: HMSAction, deviceInfo: string, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.DEVICE_IN_USE,
'DeviceInUse',
action,
`[TRACK]: Capture device is in use by another application - ${deviceInfo}`,
description,
deviceInfo as HMSTrackExceptionTrackType,
);
},

DeviceLostMidway(action: HMSAction, deviceInfo: string, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.DEVICE_LOST_MIDWAY,
'DeviceLostMidway',
action,
`Lost access to capture device midway - ${deviceInfo}`,
description,
deviceInfo as HMSTrackExceptionTrackType,
);
},

Expand All @@ -152,113 +158,123 @@ export const ErrorFactory = {
description = '',
message = `There is no media to return. Please select either video or audio or both.`,
) {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.NOTHING_TO_RETURN,
'NothingToReturn',
action,
message,
description,
HMSTrackExceptionTrackType.AUDIO_VIDEO,
);
},

InvalidVideoSettings(action: HMSAction, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.INVALID_VIDEO_SETTINGS,
'InvalidVideoSettings',
action,
`Cannot enable simulcast when no video settings are provided`,
description,
HMSTrackExceptionTrackType.VIDEO,
);
},

AutoplayBlocked(action: HMSAction, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.AUTOPLAY_ERROR,
'AutoplayBlocked',
action,
"Autoplay blocked because the user didn't interact with the document first",
description,
HMSTrackExceptionTrackType.AUDIO,
);
},

CodecChangeNotPermitted(action: HMSAction, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.CODEC_CHANGE_NOT_PERMITTED,
'CodecChangeNotPermitted',
action,
`Codec can't be changed mid call.`,
description,
HMSTrackExceptionTrackType.AUDIO_VIDEO,
);
},

OverConstrained(action: HMSAction, deviceInfo: string, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.OVER_CONSTRAINED,
'OverConstrained',
action,
`[TRACK]: Requested constraints cannot be satisfied with the device hardware - ${deviceInfo}`,
description,
deviceInfo as HMSTrackExceptionTrackType,
);
},

NoAudioDetected(action: HMSAction, description = 'Please check the mic or use another audio input') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.NO_AUDIO_DETECTED,
'NoAudioDetected',
action,
'No audio input detected from microphone',
description,
HMSTrackExceptionTrackType.AUDIO,
);
},

SystemDeniedPermission(action: HMSAction, deviceInfo: string, description = '') {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.SYSTEM_DENIED_PERMISSION,
'SystemDeniedPermission',
action,
`Operating System denied permission to access capture device - ${deviceInfo}`,
description,
deviceInfo as HMSTrackExceptionTrackType,
);
},

CurrentTabNotShared() {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.CURRENT_TAB_NOT_SHARED,
'CurrentTabNotShared',
HMSAction.TRACK,
'The app requires you to share the current tab',
'You must screen share the current tab in order to proceed',
HMSTrackExceptionTrackType.SCREEN,
);
},

AudioPlaybackError(description: string) {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.AUDIO_PLAYBACK_ERROR,
'Audio playback error',
HMSAction.TRACK,
description,
description,
HMSTrackExceptionTrackType.AUDIO,
);
},

SelectedDeviceMissing(deviceType: string) {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.SELECTED_DEVICE_MISSING,
'SelectedDeviceMissing',
HMSAction.TRACK,
`Could not detect selected ${deviceType} device`,
`Please check connection to the ${deviceType} device`,
false,
deviceType as HMSTrackExceptionTrackType,
);
},

NoDataInTrack(description: string) {
return new HMSException(
return new HMSTrackException(
ErrorCodes.TracksErrors.NO_DATA,
'Track does not have any data',
HMSAction.TRACK,
description,
'This could possibily due to another application taking priority over the access to camera or microphone or due to an incoming call',
HMSTrackExceptionTrackType.AUDIO_VIDEO,
);
},
},
Expand Down
16 changes: 8 additions & 8 deletions packages/hms-video-store/src/error/HMSException.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ export class HMSException extends Error implements IAnalyticsPropertiesProvider

toString() {
return `{
code: ${this.code};
name: ${this.name};
action: ${this.action};
message: ${this.message};
description: ${this.description};
isTerminal: ${this.isTerminal};
nativeError: ${this.nativeError?.message};
}`;
code: ${this.code};
name: ${this.name};
action: ${this.action};
message: ${this.message};
description: ${this.description};
isTerminal: ${this.isTerminal};
nativeError: ${this.nativeError?.message};
}`;
}
}
37 changes: 37 additions & 0 deletions packages/hms-video-store/src/error/HMSTrackException.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { HMSAction } from './HMSAction';
import { HMSException } from './HMSException';
import { HMSTrackExceptionTrackType } from '../media/tracks/HMSTrackExceptionTrackType';
import { HMSSignalMethod } from '../signal/jsonrpc/models';

export class HMSTrackException extends HMSException {
constructor(
public readonly code: number,
public name: string,
action: HMSAction | HMSSignalMethod,
public message: string,
public description: string,
public trackType: HMSTrackExceptionTrackType,
) {
super(code, name, action, message, description, false);
}

toAnalyticsProperties() {
return {
...super.toAnalyticsProperties(),
track_type: this.trackType,
};
}

toString() {
return `{
code: ${this.code};
name: ${this.name};
action: ${this.action};
message: ${this.message};
description: ${this.description};
isTerminal: ${this.isTerminal};
nativeError: ${this.nativeError?.message};
trackType: ${this.trackType};
}`;
}
}
16 changes: 9 additions & 7 deletions packages/hms-video-store/src/error/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import adapter from 'webrtc-adapter';
import { ErrorFactory } from './ErrorFactory';
import { HMSAction } from './HMSAction';
import { HMSException } from './HMSException';
import { HMSTrackException } from './HMSTrackException';

export enum HMSGetMediaActions {
UNKNOWN = 'unknown(video or audio)',
Expand All @@ -13,13 +13,15 @@ export enum HMSGetMediaActions {

function getDefaultError(error: string, deviceInfo: string) {
const message = error.toLowerCase();
let exception = ErrorFactory.TracksErrors.GenericTrack(HMSAction.TRACK, error);

if (message.includes('device not found')) {
return ErrorFactory.TracksErrors.DeviceNotAvailable(HMSAction.TRACK, deviceInfo, error);
exception = ErrorFactory.TracksErrors.DeviceNotAvailable(HMSAction.TRACK, deviceInfo, error);
} else if (message.includes('permission denied')) {
return ErrorFactory.TracksErrors.CantAccessCaptureDevice(HMSAction.TRACK, deviceInfo, error);
} else {
return ErrorFactory.TracksErrors.GenericTrack(HMSAction.TRACK, error);
exception = ErrorFactory.TracksErrors.CantAccessCaptureDevice(HMSAction.TRACK, deviceInfo, error);
}

return exception;
}

/**
Expand All @@ -31,7 +33,7 @@ function getDefaultError(error: string, deviceInfo: string) {
* System blocked - NotAllowedError - Permission denied by system
*/
// eslint-disable-next-line complexity
function convertMediaErrorToHMSException(err: Error, deviceInfo = ''): HMSException {
function convertMediaErrorToHMSException(err: Error, deviceInfo = ''): HMSTrackException {
/**
* Note: Adapter detects all chromium browsers as 'chrome'
*/
Expand Down Expand Up @@ -70,7 +72,7 @@ function convertMediaErrorToHMSException(err: Error, deviceInfo = ''): HMSExcept
}
}

export function BuildGetMediaError(err: Error, deviceInfo: string): HMSException {
export function BuildGetMediaError(err: Error, deviceInfo: string): HMSTrackException {
const exception = convertMediaErrorToHMSException(err, deviceInfo);
exception.addNativeError(err);
return exception;
Expand Down
2 changes: 2 additions & 0 deletions packages/hms-video-store/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,5 @@ export type {
} from './internal';
export * from './diagnostics';
export { DomainCategory } from './analytics/AnalyticsEventDomains';

export { HMSTrackExceptionTrackType } from './media/tracks/HMSTrackExceptionTrackType';
1 change: 1 addition & 0 deletions packages/hms-video-store/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './utils/media';
export * from './utils/device-error';
export * from './utils/support';
export * from './error/HMSException';
export * from './error/HMSTrackException';
export * from './interfaces';
export * from './rtc-stats';
export * from './plugins';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum HMSTrackExceptionTrackType {
AUDIO = 'audio',
VIDEO = 'video',
AUDIO_VIDEO = 'audio, video',
SCREEN = 'screen',
}
13 changes: 10 additions & 3 deletions packages/hms-video-store/src/reactive-store/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
HMSRoom,
HMSScreenVideoTrack,
HMSTrack,
HMSTrackException,
HMSTrackFacingMode,
HMSVideoTrack,
} from '../schema';
Expand Down Expand Up @@ -203,8 +204,9 @@ export class SDKToHMS {
};
}

static convertException(sdkException: sdkTypes.HMSException): HMSException {
return {
static convertException(sdkException: sdkTypes.HMSException): HMSException | HMSTrackException {
const isTrackException = 'trackType' in sdkException;
const exp = {
code: sdkException.code,
action: sdkException.action,
name: sdkException.name,
Expand All @@ -213,7 +215,12 @@ export class SDKToHMS {
isTerminal: sdkException.isTerminal,
nativeError: sdkException.nativeError,
timestamp: new Date(),
};
} as HMSException;
if (isTrackException) {
(exp as HMSTrackException).trackType = (sdkException as sdkTypes.HMSTrackException)?.trackType;
return exp as HMSTrackException;
}
return exp;
}

static convertDeviceChangeUpdate(sdkDeviceChangeEvent: sdkTypes.HMSDeviceChangeEvent): HMSDeviceChangeEvent {
Expand Down
Loading
Loading