Merge pull request #3428 from element-hq/valere/restricted_room_creation_error
Display a custom error for restricted SFU config error
This commit is contained in:
@@ -94,6 +94,8 @@
|
|||||||
"matrix_rtc_focus_missing": "The server is not configured to work with {{brand}}. Please contact your server admin (Domain: {{domain}}, Error Code: {{ errorCode }}).",
|
"matrix_rtc_focus_missing": "The server is not configured to work with {{brand}}. Please contact your server admin (Domain: {{domain}}, Error Code: {{ errorCode }}).",
|
||||||
"open_elsewhere": "Opened in another tab",
|
"open_elsewhere": "Opened in another tab",
|
||||||
"open_elsewhere_description": "{{brand}} has been opened in another tab. If that doesn't sound right, try reloading the page.",
|
"open_elsewhere_description": "{{brand}} has been opened in another tab. If that doesn't sound right, try reloading the page.",
|
||||||
|
"room_creation_restricted": "Failed to create call",
|
||||||
|
"room_creation_restricted_description": "Call creation might be restricted to authorized users only. Try again later, or contact your server admin if the problem persists.",
|
||||||
"unexpected_ec_error": "An unexpected error occurred (<0>Error Code:</0> <1>{{ errorCode }}</1>). Please contact your server admin."
|
"unexpected_ec_error": "An unexpected error occurred (<0>Error Code:</0> <1>{{ errorCode }}</1>). Please contact your server admin."
|
||||||
},
|
},
|
||||||
"group_call_loader": {
|
"group_call_loader": {
|
||||||
|
|||||||
@@ -72,3 +72,56 @@ test("Should automatically retry non fatal JWT errors", async ({
|
|||||||
await hasRetriedPromise;
|
await hasRetriedPromise;
|
||||||
await expect(page.getByTestId("video").first()).toBeVisible();
|
await expect(page.getByTestId("video").first()).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Should show error screen if call creation is restricted", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await page.goto("/");
|
||||||
|
|
||||||
|
// We need the socket connection to fail, but this cannot be done by using the websocket route.
|
||||||
|
// Instead, we will trick the app by returning a bad URL for the SFU that will not be reachable an error out.
|
||||||
|
await page.route(
|
||||||
|
"**/matrix-rtc.m.localhost/livekit/jwt/sfu/get",
|
||||||
|
async (route) =>
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: "application/json",
|
||||||
|
body: JSON.stringify({
|
||||||
|
url: "wss://badurltotricktest/livekit/sfu",
|
||||||
|
jwt: "FAKE",
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Then if the socket connection fails, livekit will try to validate the token!
|
||||||
|
// Livekit will not auto_create anymore and will return a 404 error.
|
||||||
|
await page.route(
|
||||||
|
"**/badurltotricktest/livekit/sfu/rtc/validate?**",
|
||||||
|
async (route) =>
|
||||||
|
await route.fulfill({
|
||||||
|
status: 404,
|
||||||
|
contentType: "text/plain",
|
||||||
|
body: "requested room does not exist",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.pause();
|
||||||
|
|
||||||
|
await page.getByTestId("home_callName").click();
|
||||||
|
await page.getByTestId("home_callName").fill("HelloCall");
|
||||||
|
await page.getByTestId("home_displayName").click();
|
||||||
|
await page.getByTestId("home_displayName").fill("John Doe");
|
||||||
|
await page.getByTestId("home_go").click();
|
||||||
|
|
||||||
|
// Join the call
|
||||||
|
await page.getByTestId("lobby_joinCall").click();
|
||||||
|
|
||||||
|
await page.pause();
|
||||||
|
// Should fail
|
||||||
|
await expect(page.getByText("Failed to create call")).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.getByText(
|
||||||
|
/Call creation might be restricted to authorized users only/,
|
||||||
|
),
|
||||||
|
).toBeVisible();
|
||||||
|
});
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
|||||||
import {
|
import {
|
||||||
ElementCallError,
|
ElementCallError,
|
||||||
InsufficientCapacityError,
|
InsufficientCapacityError,
|
||||||
|
SFURoomCreationRestrictedError,
|
||||||
UnknownCallError,
|
UnknownCallError,
|
||||||
} from "../utils/errors.ts";
|
} from "../utils/errors.ts";
|
||||||
import { AbortHandle } from "../utils/abortHandle.ts";
|
import { AbortHandle } from "../utils/abortHandle.ts";
|
||||||
@@ -184,11 +185,19 @@ async function connectAndPublish(
|
|||||||
// participant limits.
|
// participant limits.
|
||||||
// LiveKit Cloud uses 429 for connection limits.
|
// LiveKit Cloud uses 429 for connection limits.
|
||||||
// Either way, all these errors can be explained as "insufficient capacity".
|
// Either way, all these errors can be explained as "insufficient capacity".
|
||||||
if (
|
if (e instanceof ConnectionError) {
|
||||||
e instanceof ConnectionError &&
|
if (e.status === 503 || e.status === 200 || e.status === 429) {
|
||||||
(e.status === 503 || e.status === 200 || e.status === 429)
|
throw new InsufficientCapacityError();
|
||||||
)
|
}
|
||||||
throw new InsufficientCapacityError();
|
if (e.status === 404) {
|
||||||
|
// error msg is "Could not establish signal connection: requested room does not exist"
|
||||||
|
// The room does not exist. There are two different modes of operation for the SFU:
|
||||||
|
// - the room is created on the fly when connecting (livekit `auto_create` option)
|
||||||
|
// - Only authorized users can create rooms, so the room must exist before connecting (done by the auth jwt service)
|
||||||
|
// In the first case there will not be a 404, so we are in the second case.
|
||||||
|
throw new SFURoomCreationRestrictedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export enum ErrorCode {
|
|||||||
INSUFFICIENT_CAPACITY_ERROR = "INSUFFICIENT_CAPACITY_ERROR",
|
INSUFFICIENT_CAPACITY_ERROR = "INSUFFICIENT_CAPACITY_ERROR",
|
||||||
E2EE_NOT_SUPPORTED = "E2EE_NOT_SUPPORTED",
|
E2EE_NOT_SUPPORTED = "E2EE_NOT_SUPPORTED",
|
||||||
OPEN_ID_ERROR = "OPEN_ID_ERROR",
|
OPEN_ID_ERROR = "OPEN_ID_ERROR",
|
||||||
|
SFU_ERROR = "SFU_ERROR",
|
||||||
UNKNOWN_ERROR = "UNKNOWN_ERROR",
|
UNKNOWN_ERROR = "UNKNOWN_ERROR",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,3 +130,14 @@ export class InsufficientCapacityError extends ElementCallError {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SFURoomCreationRestrictedError extends ElementCallError {
|
||||||
|
public constructor() {
|
||||||
|
super(
|
||||||
|
t("error.room_creation_restricted"),
|
||||||
|
ErrorCode.SFU_ERROR,
|
||||||
|
ErrorCategory.CONFIGURATION_ISSUE,
|
||||||
|
t("error.room_creation_restricted_description"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user