fix(lotus): show the SFU token service's refusal reason instead of "Something went wrong"

When the voice-limit guard (or any JWT service) answers 403 with a reason —
"This voice channel is full.", "You don't have permission to …" — EC wrapped it
in FailToGetOpenIdToken and the user saw the generic error page with
OPEN_ID_ERROR. A 403 MatrixError with a non-empty `error` now throws
SFUTokenRefusedError ("Can't join this call" + the server's sentence), so the
reason is the description. Other failures are unchanged. Unit-tested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
Lotus CI
2026-09-19 13:42:22 -04:00
co-authored by Claude Opus 5
parent 66bfead7f1
commit d9ac9a0fa4
4 changed files with 57 additions and 1 deletions
+20
View File
@@ -23,6 +23,8 @@ export enum ErrorCode {
E2EE_NOT_SUPPORTED = "E2EE_NOT_SUPPORTED",
STICKY_EVENTS_NOT_SUPPORTED = "STICKY_EVENTS_NOT_SUPPORTED",
OPEN_ID_ERROR = "OPEN_ID_ERROR",
/** [lotus] The SFU token service refused us with a human-readable reason (e.g. the voice-limit guard: channel full / no permission). */
SFU_TOKEN_REFUSED = "SFU_TOKEN_REFUSED",
NO_MATRIX_2_AUTHORIZATION_SERVICE = "NO_MATRIX_2_0_AUTHORIZATION_SERVICE",
SFU_ERROR = "SFU_ERROR",
UNKNOWN_ERROR = "UNKNOWN_ERROR",
@@ -234,6 +236,24 @@ export class FailToStartLivekitConnection extends ElementCallError {
/**
* Error indicating that a LiveKit's server has hit its track limits.
*/
/**
* [lotus] The SFU token service answered 403 with a reason we can show verbatim
* — the voice-limit guard says things like "This voice channel is full." or
* "You don't have permission to share your screen here." Without this the user
* only ever saw "Something went wrong (OPEN_ID_ERROR)".
*/
export class SFUTokenRefusedError extends ElementCallError {
public constructor(reason: string, cause?: Error) {
super(
t("error.sfu_token_refused"),
ErrorCode.SFU_TOKEN_REFUSED,
ErrorCategory.CONFIGURATION_ISSUE,
reason,
cause,
);
}
}
export class InsufficientCapacityError extends ElementCallError {
public constructor() {
super(