diff --git a/.changeset/nine-peas-approve.md b/.changeset/nine-peas-approve.md new file mode 100644 index 000000000..ddcc87e80 --- /dev/null +++ b/.changeset/nine-peas-approve.md @@ -0,0 +1,6 @@ +--- +"@livekit/components-core": patch +"@livekit/components-react": patch +--- + +Forward track toggle errors diff --git a/packages/core/etc/components-core.api.md b/packages/core/etc/components-core.api.md index 064e26320..ebf93d0f0 100644 --- a/packages/core/etc/components-core.api.md +++ b/packages/core/etc/components-core.api.md @@ -490,7 +490,7 @@ export function setupManualToggle(): { }; // @public (undocumented) -export function setupMediaToggle(source: T, room: Room, options?: CaptureOptionsBySource, publishOptions?: TrackPublishOptions): MediaToggleType; +export function setupMediaToggle(source: T, room: Room, options?: CaptureOptionsBySource, publishOptions?: TrackPublishOptions, onError?: (error: Error) => void): MediaToggleType; // Warning: (ae-incompatible-release-tags) The symbol "setupMediaTrack" is marked as @public, but its signature references "TrackIdentifier" which is marked as @internal // diff --git a/packages/core/src/components/mediaToggle.ts b/packages/core/src/components/mediaToggle.ts index 8704520f9..251b38cdd 100644 --- a/packages/core/src/components/mediaToggle.ts +++ b/packages/core/src/components/mediaToggle.ts @@ -37,6 +37,7 @@ export function setupMediaToggle( room: Room, options?: CaptureOptionsBySource, publishOptions?: TrackPublishOptions, + onError?: (error: Error) => void, ): MediaToggleType { const { localParticipant } = room; @@ -96,6 +97,12 @@ export function setupMediaToggle( default: break; } + } catch (e) { + if (onError && e instanceof Error) { + onError?.(e); + } else { + throw e; + } } finally { pendingSubject.next(false); // trigger observable update diff --git a/packages/react/etc/components-react.api.md b/packages/react/etc/components-react.api.md index b7fcfec27..dc9a1567e 100644 --- a/packages/react/etc/components-react.api.md +++ b/packages/react/etc/components-react.api.md @@ -642,6 +642,8 @@ export interface TrackToggleProps extends Omit void; // (undocumented) + onDeviceError?: (error: Error) => void; + // (undocumented) publishOptions?: TrackPublishOptions; // (undocumented) showIcon?: boolean; @@ -1089,7 +1091,7 @@ export type UseTracksOptions = { }; // @public -export function useTrackToggle({ source, onChange, initialState, captureOptions, publishOptions, ...rest }: UseTrackToggleProps): { +export function useTrackToggle({ source, onChange, initialState, captureOptions, publishOptions, onDeviceError, ...rest }: UseTrackToggleProps): { toggle: (forceState?: boolean | undefined, captureOptions?: CaptureOptionsBySource | undefined) => Promise; enabled: boolean; pending: boolean; diff --git a/packages/react/src/components/controls/TrackToggle.tsx b/packages/react/src/components/controls/TrackToggle.tsx index 9620ddf9b..c80969f39 100644 --- a/packages/react/src/components/controls/TrackToggle.tsx +++ b/packages/react/src/components/controls/TrackToggle.tsx @@ -17,6 +17,7 @@ export interface TrackToggleProps onChange?: (enabled: boolean, isUserInitiated: boolean) => void; captureOptions?: CaptureOptionsBySource; publishOptions?: TrackPublishOptions; + onDeviceError?: (error: Error) => void; } /** diff --git a/packages/react/src/hooks/useTrackToggle.ts b/packages/react/src/hooks/useTrackToggle.ts index 81d3d31a2..30ea9a91a 100644 --- a/packages/react/src/hooks/useTrackToggle.ts +++ b/packages/react/src/hooks/useTrackToggle.ts @@ -27,6 +27,7 @@ export function useTrackToggle({ initialState, captureOptions, publishOptions, + onDeviceError, ...rest }: UseTrackToggleProps) { const room = useMaybeRoomContext(); @@ -37,9 +38,9 @@ export function useTrackToggle({ const { toggle, className, pendingObserver, enabledObserver } = React.useMemo( () => room - ? setupMediaToggle(source, room, captureOptions, publishOptions) + ? setupMediaToggle(source, room, captureOptions, publishOptions, onDeviceError) : setupManualToggle(), - [room, source, JSON.stringify(captureOptions), JSON.stringify(publishOptions)], + [room, source, JSON.stringify(captureOptions), publishOptions], ); const pending = useObservableState(pendingObserver, false);