diff --git a/src/utils/direct-messages.ts b/src/utils/direct-messages.ts index 42f1febf8f..fcfb042903 100644 --- a/src/utils/direct-messages.ts +++ b/src/utils/direct-messages.ts @@ -89,7 +89,7 @@ export async function createRoomFromLocalRoom(client: MatrixClient, localRoom: L if (!roomId) throw new Error(`startDm for local room ${localRoom.roomId} didn't return a room Id`); localRoom.actualRoomId = roomId; - return waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom); + return waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom, roomId); }, () => { logger.warn(`Error creating DM for local room ${localRoom.roomId}`); diff --git a/src/utils/local-room.ts b/src/utils/local-room.ts index fbfa050800..fa5a34b593 100644 --- a/src/utils/local-room.ts +++ b/src/utils/local-room.ts @@ -22,6 +22,15 @@ import { LocalRoom, LocalRoomState } from "../models/LocalRoom"; import { isLocalRoom } from "./localRoom/isLocalRoom"; import { isRoomReady } from "./localRoom/isRoomReady"; +const isActualRoomIdDefined = (actualRoomId: string | undefined): actualRoomId is string => { + if (actualRoomId === undefined) { + // should not happen + throw new Error("Local room in CREATED state without actual room Id occurred"); + } + + return true; +}; + /** * Does a room action: * For non-local rooms it calls fn directly. @@ -43,7 +52,7 @@ export async function doMaybeLocalRoomAction( if (isLocalRoom(roomId)) { const room = client.getRoom(roomId) as LocalRoom; - if (room.isCreated) { + if (room.isCreated && isActualRoomIdDefined(room.actualRoomId)) { return fn(room.actualRoomId); } @@ -69,30 +78,36 @@ export async function doMaybeLocalRoomAction( * @async * @param {MatrixClient} client * @param {LocalRoom} localRoom + * @param actualRoomId Id of the actual room * @returns {Promise} Resolved to the actual room id */ export async function waitForRoomReadyAndApplyAfterCreateCallbacks( client: MatrixClient, localRoom: LocalRoom, + actualRoomId: string, ): Promise { if (isRoomReady(client, localRoom)) { - return applyAfterCreateCallbacks(localRoom, localRoom.actualRoomId).then(() => { + return applyAfterCreateCallbacks(localRoom, actualRoomId).then(() => { localRoom.state = LocalRoomState.CREATED; client.emit(ClientEvent.Room, localRoom); - return Promise.resolve(localRoom.actualRoomId); + return Promise.resolve(actualRoomId); }); } - return new Promise((resolve) => { + return new Promise((resolve, reject) => { const finish = (): void => { if (checkRoomStateIntervalHandle) clearInterval(checkRoomStateIntervalHandle); if (stopgapTimeoutHandle) clearTimeout(stopgapTimeoutHandle); - applyAfterCreateCallbacks(localRoom, localRoom.actualRoomId).then(() => { - localRoom.state = LocalRoomState.CREATED; - client.emit(ClientEvent.Room, localRoom); - resolve(localRoom.actualRoomId); - }); + applyAfterCreateCallbacks(localRoom, actualRoomId) + .then(() => { + localRoom.state = LocalRoomState.CREATED; + client.emit(ClientEvent.Room, localRoom); + resolve(actualRoomId); + }) + .catch((err) => { + reject(err); + }); }; const stopgapFinish = (): void => { diff --git a/test/utils/direct-messages-test.ts b/test/utils/direct-messages-test.ts index 54222aae38..3e697fb459 100644 --- a/test/utils/direct-messages-test.ts +++ b/test/utils/direct-messages-test.ts @@ -196,7 +196,11 @@ describe("direct-messages", () => { const result = await dmModule.createRoomFromLocalRoom(mockClient, localRoom); expect(result).toBe(room1.roomId); expect(localRoom.state).toBe(LocalRoomState.CREATING); - expect(waitForRoomReadyAndApplyAfterCreateCallbacks).toHaveBeenCalledWith(mockClient, localRoom); + expect(waitForRoomReadyAndApplyAfterCreateCallbacks).toHaveBeenCalledWith( + mockClient, + localRoom, + room1.roomId, + ); }); }); }); diff --git a/test/utils/local-room-test.ts b/test/utils/local-room-test.ts index 8a319cf411..7aadef65a9 100644 --- a/test/utils/local-room-test.ts +++ b/test/utils/local-room-test.ts @@ -108,7 +108,11 @@ describe("local-room", () => { }); it("should invoke the callbacks, set the room state to created and return the actual room id", async () => { - const result = await localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom); + const result = await localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks( + client, + localRoom, + room1.roomId, + ); expect(localRoom.state).toBe(LocalRoomState.CREATED); expect(localRoomCallbackRoomId).toBe(room1.roomId); expect(result).toBe(room1.roomId); @@ -121,7 +125,11 @@ describe("local-room", () => { }); it("should invoke the callbacks, set the room state to created and return the actual room id", async () => { - const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom); + const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks( + client, + localRoom, + room1.roomId, + ); jest.advanceTimersByTime(5000); const roomId = await prom; expect(localRoom.state).toBe(LocalRoomState.CREATED); @@ -137,7 +145,11 @@ describe("local-room", () => { }); it("should invoke the callbacks, set the room state to created and return the actual room id", async () => { - const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks(client, localRoom); + const prom = localRoomModule.waitForRoomReadyAndApplyAfterCreateCallbacks( + client, + localRoom, + room1.roomId, + ); mocked(isRoomReady).mockReturnValue(true); jest.advanceTimersByTime(500); const roomId = await prom;