diff --git a/apps/web/src/stores/RoomViewStore.tsx b/apps/web/src/stores/RoomViewStore.tsx index 73050916619..2d2063534a7 100644 --- a/apps/web/src/stores/RoomViewStore.tsx +++ b/apps/web/src/stores/RoomViewStore.tsx @@ -148,7 +148,8 @@ export class RoomViewStore extends EventEmitter { // another RVS via INITIAL_STATE as they share the same underlying object. Mostly relevant for tests. private state = utils.deepCopy(INITIAL_STATE); - private dis?: MatrixDispatcher; + // this is defacto always assigned as `resetDispatcher` is called in the constructor. + private dis!: MatrixDispatcher; private dispatchToken?: string; public constructor( @@ -195,7 +196,7 @@ export class RoomViewStore extends EventEmitter { // Fired so we can reduce dependency on event emitters to this store, which is relatively // central to the application and can easily cause import cycles. - this.dis?.dispatch({ + this.dis.dispatch({ action: Action.ActiveRoomChanged, oldRoomId: lastRoomId, newRoomId: this.state.roomId, @@ -302,7 +303,7 @@ export class RoomViewStore extends EventEmitter { // if the room is displayed in a module, we don't want to change the room view if (roomId && this.isRoomDisplayedInModule(roomId)) return; - this.dis?.dispatch({ + this.dis.dispatch({ action: Action.ViewRoom, room_id: payload.event.getRoomId(), replyingToEvent: payload.event, @@ -415,7 +416,7 @@ export class RoomViewStore extends EventEmitter { await this.stores.slidingSyncManager.setRoomVisible(payload.room_id); // Re-fire the payload: we won't re-process it because the prev room ID == payload room ID now - this.dis?.dispatch({ + this.dis.dispatch({ ...payload, }); return; @@ -466,7 +467,7 @@ export class RoomViewStore extends EventEmitter { viaServers: payload.via_servers, }; } - this.dis?.dispatch(joinPayload); + this.dis.dispatch(joinPayload); } if (room) { @@ -505,7 +506,7 @@ export class RoomViewStore extends EventEmitter { viaServers = result.servers; } catch (err) { logger.error("RVS failed to get room id for alias: ", err); - this.dis?.dispatch({ + this.dis.dispatch({ action: Action.ViewRoomError, room_id: null, room_alias: payload.room_alias, @@ -516,7 +517,7 @@ export class RoomViewStore extends EventEmitter { } // Re-fire the payload with the newly found room_id - this.dis?.dispatch({ + this.dis.dispatch({ ...payload, room_id: roomId, via_servers: viaServers, @@ -545,9 +546,22 @@ export class RoomViewStore extends EventEmitter { }); // take a copy of roomAlias, roomId & viaServers as they may change by the time the join is complete - const { roomAlias, roomId = payload.roomId, viaServers = [] } = this.state; + const { roomAlias, viaServers = [] } = this.state; + // fall back to the payload's roomId explicitly since it is always the room we were asked to join + const roomId = this.state.roomId ?? payload.roomId; // prefer the room alias if we have one as it allows joining over federation even with no viaServers - const address = roomAlias || roomId!; + const address = roomAlias || roomId; + + if (!address) { + logger.error("Cannot join room: no room ID or alias to join", payload); + this.dis.dispatch({ + action: Action.JoinRoomError, + roomId, + err: new UserFriendlyError("room|error_join_unknown", { cause: undefined }), + canAskToJoin: payload.canAskToJoin, + }); + return; + } const joinOpts: IJoinRoomOpts = { viaServers, @@ -568,14 +582,14 @@ export class RoomViewStore extends EventEmitter { // We do *not* clear the 'joining' flag because the Room object and/or our 'joined' member event may not // have come down the sync stream yet, and that's the point at which we'd consider the user joined to the // room. - this.dis?.dispatch({ + this.dis.dispatch({ action: Action.JoinRoomReady, - roomId: roomId!, + roomId, metricsTrigger: payload.metricsTrigger, }); } catch (err) { logger.error("Error thrown while handling joinRoom", err); - this.dis?.dispatch({ + this.dis.dispatch({ action: Action.JoinRoomError, roomId, err: err instanceof Error ? err : new UserFriendlyError("room|error_join_unknown", { cause: err }), @@ -583,7 +597,7 @@ export class RoomViewStore extends EventEmitter { }); if (payload.canAskToJoin && err instanceof MatrixError && err.httpStatus === 403) { - this.dis?.dispatch({ action: Action.PromptAskToJoin }); + this.dis.dispatch({ action: Action.PromptAskToJoin }); } } } @@ -665,7 +679,7 @@ export class RoomViewStore extends EventEmitter { */ public resetDispatcher(dis: MatrixDispatcher): void { if (this.dispatchToken) { - this.dis?.unregister(this.dispatchToken); + this.dis.unregister(this.dispatchToken); } this.dis = dis; if (dis) {