From 5d0047aebe105648dba90f440cbd9eb765fe778b Mon Sep 17 00:00:00 2001 From: fkwp Date: Wed, 10 Jun 2026 12:49:28 +0200 Subject: [PATCH] Use error.cause instead of name to detect sticky-events failure --- src/room/GroupCallView.test.tsx | 28 ++++++++++++++++++++-------- src/room/GroupCallView.tsx | 16 +++++++++++----- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/room/GroupCallView.test.tsx b/src/room/GroupCallView.test.tsx index 92c27077f..53b18cde0 100644 --- a/src/room/GroupCallView.test.tsx +++ b/src/room/GroupCallView.test.tsx @@ -19,7 +19,12 @@ import { vitest, } from "vitest"; import { render, waitFor, screen, act } from "@testing-library/react"; -import { type MatrixClient, JoinRule, type RoomState } from "matrix-js-sdk"; +import { + type MatrixClient, + JoinRule, + type RoomState, + UnsupportedStickyEventsEndpointError, +} from "matrix-js-sdk"; import { MatrixRTCSessionEvent, type MatrixRTCSession, @@ -410,19 +415,26 @@ test.skip("GroupCallView shows errors that occur during joining", async () => { screen.getByText("Call is not supported"); }); -test("translates UnsupportedStickyEventsEndpointError to the StickyEventsRequiredError screen", async () => { - // Match the shape the SDK emits on - // MatrixRTCSessionEvent.MembershipManagerError when matrix_2_0 mode is - // configured but the homeserver does not advertise MSC4354. - const stickyError = new Error("Server does not support the sticky events"); - stickyError.name = "UnsupportedStickyEventsEndpointError"; +test("translates wrapped UnsupportedStickyEventsEndpointError to the StickyEventsRequiredError screen", async () => { + // Mirror the shape the SDK emits: the MembershipManager scheduler wraps + // the original UnsupportedStickyEventsEndpointError in a generic Error + // but preserves the original on `.cause`. + const stickyError = new UnsupportedStickyEventsEndpointError( + "Server does not support the sticky events", + "sendStickyEvent", + ); + const wrappedError = new Error( + "The MembershipManager shut down because of the end condition: " + + String(stickyError), + { cause: stickyError }, + ); const { rtcSession } = createGroupCallView(null, true, { withErrorBoundary: true, }); await act(() => - rtcSession.emit(MatrixRTCSessionEvent.MembershipManagerError, stickyError), + rtcSession.emit(MatrixRTCSessionEvent.MembershipManagerError, wrappedError), ); await screen.findByText("Homeserver does not support Matrix 2.0 calls"); diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index 0879efda8..09ea15be3 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -13,7 +13,12 @@ import { useMemo, useState, } from "react"; -import { type MatrixClient, JoinRule, type Room } from "matrix-js-sdk"; +import { + type MatrixClient, + JoinRule, + type Room, + UnsupportedStickyEventsEndpointError, +} from "matrix-js-sdk"; import { Room as LivekitRoom, isE2EESupported as isE2EESupportedBrowser, @@ -164,12 +169,13 @@ export const GroupCallView: FC = ({ rtcSession, MatrixRTCSessionEvent.MembershipManagerError, (error) => { - // The SDK throws this typed error when matrix_rtc_mode=matrix_2_0 is in - // effect but the homeserver does not advertise MSC4354 (sticky events). - // Surface the actual cause instead of a generic connection-lost screen. + // When matrix_rtc_mode=matrix_2_0 is in effect but the homeserver does + // not advertise MSC4354 (sticky events), the SDK throws an + // `UnsupportedStickyEventsEndpointError`. The MembershipManager + // scheduler wraps it and exposes the original via `.cause`. if ( error instanceof Error && - error.name === "UnsupportedStickyEventsEndpointError" + error.cause instanceof UnsupportedStickyEventsEndpointError ) { setExternalError(new StickyEventsRequiredError()); } else {