diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 28ffae5656..4a0aca7aed 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -878,6 +878,8 @@ "Please contact your homeserver administrator.": "Please contact your homeserver administrator.", "The person who invited you has already left.": "The person who invited you has already left.", "The person who invited you has already left, or their server is offline.": "The person who invited you has already left, or their server is offline.", + "You attempted to join using a room ID without providing a list of servers to join through. Room IDs are internal identifiers and cannot be used to join a room without additional information.": "You attempted to join using a room ID without providing a list of servers to join through. Room IDs are internal identifiers and cannot be used to join a room without additional information.", + "If you know a room address, try joining through that instead.": "If you know a room address, try joining through that instead.", "Failed to join": "Failed to join", "Connection lost": "Connection lost", "You were disconnected from the call. (Error: %(message)s)": "You were disconnected from the call. (Error: %(message)s)", diff --git a/src/stores/RoomViewStore.tsx b/src/stores/RoomViewStore.tsx index 86f0f6bdb2..47bc9b959b 100644 --- a/src/stores/RoomViewStore.tsx +++ b/src/stores/RoomViewStore.tsx @@ -593,7 +593,7 @@ export class RoomViewStore extends EventEmitter { ); } else if (err.httpStatus === 404) { const invitingUserId = this.getInvitingUserId(roomId); - // only provide a better error message for invites + // provide a better error message for invites if (invitingUserId) { // if the inviting user is on the same HS, there can only be one cause: they left. if (invitingUserId.endsWith(`:${MatrixClientPeg.get().getDomain()}`)) { @@ -602,6 +602,23 @@ export class RoomViewStore extends EventEmitter { description = _t("The person who invited you has already left, or their server is offline."); } } + + // provide a more detailed error than "No known servers" when attempting to + // join using a room ID and no via servers + if (roomId === this.state.roomId && this.state.viaServers.length === 0) { + description = ( +
+ {_t( + "You attempted to join using a room ID without providing a list " + + "of servers to join through. Room IDs are internal identifiers and " + + "cannot be used to join a room without additional information.", + )} +
+
+ {_t("If you know a room address, try joining through that instead.")} +
+ ); + } } Modal.createDialog(ErrorDialog, { @@ -615,7 +632,9 @@ export class RoomViewStore extends EventEmitter { joining: false, joinError: payload.err, }); - this.showJoinRoomError(payload.err, payload.roomId); + if (payload.err) { + this.showJoinRoomError(payload.err, payload.roomId); + } } public reset(): void { diff --git a/test/stores/RoomViewStore-test.ts b/test/stores/RoomViewStore-test.ts index 87d549c370..4ca203ffd9 100644 --- a/test/stores/RoomViewStore-test.ts +++ b/test/stores/RoomViewStore-test.ts @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Room } from "matrix-js-sdk/src/matrix"; +import { mocked } from "jest-mock"; +import { MatrixError, Room } from "matrix-js-sdk/src/matrix"; import { sleep } from "matrix-js-sdk/src/utils"; import { RoomViewStore } from "../../src/stores/RoomViewStore"; @@ -284,6 +285,29 @@ describe("RoomViewStore", function () { await viewCall(); }); + it("should display an error message when the room is unreachable via the roomId", async () => { + // When + // View and wait for the room + dis.dispatch({ action: Action.ViewRoom, room_id: roomId }); + await untilDispatch(Action.ActiveRoomChanged, dis); + // Generate error to display the expected error message + const error = new MatrixError(undefined, 404); + roomViewStore.showJoinRoomError(error, roomId); + + // Check the modal props + expect(mocked(Modal).createDialog.mock.calls[0][1]).toMatchSnapshot(); + }); + + it("should display the generic error message when the roomId doesnt match", async () => { + // When + // Generate error to display the expected error message + const error = new MatrixError({ error: "my 404 error" }, 404); + roomViewStore.showJoinRoomError(error, roomId); + + // Check the modal props + expect(mocked(Modal).createDialog.mock.calls[0][1]).toMatchSnapshot(); + }); + describe("when listening to a voice broadcast", () => { let voiceBroadcastPlayback: VoiceBroadcastPlayback; diff --git a/test/stores/__snapshots__/RoomViewStore-test.ts.snap b/test/stores/__snapshots__/RoomViewStore-test.ts.snap index 64221efac4..a6b7953697 100644 --- a/test/stores/__snapshots__/RoomViewStore-test.ts.snap +++ b/test/stores/__snapshots__/RoomViewStore-test.ts.snap @@ -1,5 +1,24 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`RoomViewStore should display an error message when the room is unreachable via the roomId 1`] = ` +{ + "description":
+ You attempted to join using a room ID without providing a list of servers to join through. Room IDs are internal identifiers and cannot be used to join a room without additional information. +
+
+ If you know a room address, try joining through that instead. +
, + "title": "Failed to join", +} +`; + +exports[`RoomViewStore should display the generic error message when the roomId doesnt match 1`] = ` +{ + "description": "MatrixError: [404] my 404 error", + "title": "Failed to join", +} +`; + exports[`RoomViewStore when recording a voice broadcast and trying to view a call, it should not actually view it and show the info dialog 1`] = ` [MockFunction] { "calls": [