From 35d862ebd3e198e1ac2a02a5ed268f82890c9980 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Mon, 11 Nov 2024 15:48:53 -0500 Subject: [PATCH] Handle M_MAX_DELAY_EXCEEDED errors (#4511) * Handle M_MAX_DELAY_EXCEEDED errors Use a lower delay time if the server rejects a delay as too long. * Add test * Lint test * Update src/matrixrtc/MatrixRTCSession.ts Co-authored-by: Robin * Test computed expiry timeout value --------- Co-authored-by: Robin --- spec/unit/matrixrtc/MatrixRTCSession.spec.ts | 22 ++++++++++++++++- src/matrixrtc/MatrixRTCSession.ts | 26 +++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/spec/unit/matrixrtc/MatrixRTCSession.spec.ts b/spec/unit/matrixrtc/MatrixRTCSession.spec.ts index 6b45a93025..fb62a669c7 100644 --- a/spec/unit/matrixrtc/MatrixRTCSession.spec.ts +++ b/spec/unit/matrixrtc/MatrixRTCSession.spec.ts @@ -508,6 +508,19 @@ describe("MatrixRTCSession", () => { jest.useFakeTimers(); + // preparing the delayed disconnect should handle the delay being too long + const sendDelayedStateExceedAttempt = new Promise((resolve) => { + const error = new MatrixError({ + "errcode": "M_UNKNOWN", + "org.matrix.msc4140.errcode": "M_MAX_DELAY_EXCEEDED", + "org.matrix.msc4140.max_delay": 7500, + }); + sendDelayedStateMock.mockImplementationOnce(() => { + resolve(); + return Promise.reject(error); + }); + }); + // preparing the delayed disconnect should handle ratelimiting const sendDelayedStateAttempt = new Promise((resolve) => { const error = new MatrixError({ errcode: "M_LIMIT_EXCEEDED" }); @@ -541,7 +554,14 @@ describe("MatrixRTCSession", () => { }); }); - sess!.joinRoomSession([activeFocusConfig], activeFocus, { useLegacyMemberEvents: false }); + sess!.joinRoomSession([activeFocusConfig], activeFocus, { + useLegacyMemberEvents: false, + membershipServerSideExpiryTimeout: 9000, + }); + + expect(sess).toHaveProperty("membershipServerSideExpiryTimeout", 9000); + await sendDelayedStateExceedAttempt.then(); // needed to resolve after the send attempt catches + expect(sess).toHaveProperty("membershipServerSideExpiryTimeout", 7500); await sendDelayedStateAttempt; jest.advanceTimersByTime(5000); diff --git a/src/matrixrtc/MatrixRTCSession.ts b/src/matrixrtc/MatrixRTCSession.ts index 5d4d90ea58..046591ede1 100644 --- a/src/matrixrtc/MatrixRTCSession.ts +++ b/src/matrixrtc/MatrixRTCSession.ts @@ -184,8 +184,18 @@ export class MatrixRTCSession extends TypedEventEmitter maxDelayAllowed + ) { + this.membershipServerSideExpiryTimeoutOverride = maxDelayAllowed; + return prepareDelayedDisconnection(); + } + } logger.error("Failed to prepare delayed disconnection event:", e); } };