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": [