mirror of
https://github.com/vector-im/element-call.git
synced 2026-05-07 10:14:36 +00:00
Improve error messages for sfu auth problems
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
"reactions": "Reactions",
|
||||
"reconnecting": "Reconnecting…",
|
||||
"settings": "Settings",
|
||||
"technical_details": "Technical details",
|
||||
"unencrypted": "Not encrypted",
|
||||
"username": "Username",
|
||||
"video": "Video"
|
||||
|
||||
@@ -20,3 +20,21 @@
|
||||
color: var(--cpd-color-text-secondary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.technicalDetails {
|
||||
margin-top: var(--cpd-space-1x);
|
||||
}
|
||||
|
||||
.technicalDetailsSummary {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.technicalDetailsPre {
|
||||
margin-top: var(--cpd-space-2x);
|
||||
padding: var(--cpd-space-2x);
|
||||
background-color: var(--cpd-color-bg-subtle-secondary);
|
||||
overflow: auto;
|
||||
font-size: var(--cpd-font-size-body-sm);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type IOpenIDToken, type MatrixClient } from "matrix-js-sdk";
|
||||
import {
|
||||
type IOpenIDToken,
|
||||
type MatrixClient,
|
||||
parseErrorResponse,
|
||||
} from "matrix-js-sdk";
|
||||
import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager";
|
||||
import { type Logger } from "matrix-js-sdk/lib/logger";
|
||||
|
||||
@@ -248,7 +252,7 @@ async function getLiveKitJWT(
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("SFU Config fetch failed with status code " + res.status);
|
||||
throw parseErrorResponse(res, await res.text());
|
||||
}
|
||||
return await res.json();
|
||||
}
|
||||
@@ -308,7 +312,7 @@ export async function getLiveKitJWTWithDelayDelegation(
|
||||
if (res.status === 404) {
|
||||
throw new NotSupportedError(msg);
|
||||
} else {
|
||||
throw new Error(msg);
|
||||
throw parseErrorResponse(res, await res.text());
|
||||
}
|
||||
}
|
||||
return await res.json();
|
||||
|
||||
@@ -25,12 +25,14 @@ import {
|
||||
ConnectionLostError,
|
||||
E2EENotSupportedError,
|
||||
type ElementCallError,
|
||||
FailToGetOpenIdToken,
|
||||
InsufficientCapacityError,
|
||||
MatrixRTCTransportMissingError,
|
||||
UnknownCallError,
|
||||
} from "../utils/errors.ts";
|
||||
import { mockConfig } from "../utils/test.ts";
|
||||
import { ElementWidgetActions, type WidgetHelpers } from "../widget.ts";
|
||||
import { MatrixError } from "matrix-js-sdk";
|
||||
|
||||
test.each([
|
||||
{
|
||||
@@ -252,3 +254,69 @@ test("should have a close button in widget mode", async () => {
|
||||
);
|
||||
expect(mockWidget.api.transport.stop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("should show technical details when error has a matrixError cause", async () => {
|
||||
const underlyingError = new MatrixError(
|
||||
{
|
||||
errcode: "M_LOOKUP_FAILED",
|
||||
error: "Failed to look up user info from homeserver",
|
||||
},
|
||||
500,
|
||||
"https://matrix-rtc.m.localhost/livekit/jwt/sfu/get",
|
||||
);
|
||||
const error = new FailToGetOpenIdToken(underlyingError);
|
||||
|
||||
const TestComponent = (): ReactNode => {
|
||||
throw error;
|
||||
};
|
||||
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<GroupCallErrorBoundary
|
||||
onError={vi.fn()}
|
||||
recoveryActionHandler={vi.fn()}
|
||||
widget={null}
|
||||
>
|
||||
<TestComponent />
|
||||
</GroupCallErrorBoundary>
|
||||
</BrowserRouter>,
|
||||
);
|
||||
|
||||
await screen.findByText("Something went wrong");
|
||||
|
||||
// Technical details should be present
|
||||
const detailsElement = screen.getByText("Technical details");
|
||||
expect(detailsElement).toBeInTheDocument();
|
||||
|
||||
// Verify error details are shown
|
||||
expect(
|
||||
screen.getByText(/Failed to look up user info from homeserver/i, {
|
||||
selector: "pre",
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("should not show technical details when error has no matrix error cause", async () => {
|
||||
const error = new ConnectionLostError();
|
||||
|
||||
const TestComponent = (): ReactNode => {
|
||||
throw error;
|
||||
};
|
||||
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<GroupCallErrorBoundary
|
||||
onError={vi.fn()}
|
||||
recoveryActionHandler={vi.fn()}
|
||||
widget={null}
|
||||
>
|
||||
<TestComponent />
|
||||
</GroupCallErrorBoundary>
|
||||
</BrowserRouter>,
|
||||
);
|
||||
|
||||
await screen.findByText("Connection lost");
|
||||
|
||||
// Technical details should not be present (ConnectionLostError has no cause)
|
||||
expect(screen.queryByText("Technical details")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -34,6 +34,8 @@ import {
|
||||
import { FullScreenView } from "../FullScreenView.tsx";
|
||||
import { ErrorView } from "../ErrorView.tsx";
|
||||
import { type WidgetHelpers } from "../widget.ts";
|
||||
import styles from "../ErrorView.module.css";
|
||||
import { MatrixError } from "matrix-js-sdk";
|
||||
|
||||
export type CallErrorRecoveryAction = "reconnect"; // | "retry" ;
|
||||
|
||||
@@ -78,6 +80,9 @@ const ErrorPage: FC<ErrorPageProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
const technicalError =
|
||||
error.cause instanceof MatrixError ? error.cause : null;
|
||||
|
||||
return (
|
||||
<FullScreenView>
|
||||
<ErrorView
|
||||
@@ -95,6 +100,16 @@ const ErrorPage: FC<ErrorPageProps> = ({
|
||||
/>
|
||||
)}
|
||||
</p>
|
||||
{technicalError ? (
|
||||
<details className={styles.technicalDetails}>
|
||||
<summary className={styles.technicalDetailsSummary}>
|
||||
Technical details
|
||||
</summary>
|
||||
<pre className={styles.technicalDetailsPre}>
|
||||
{technicalError.message}
|
||||
</pre>
|
||||
</details>
|
||||
) : null}
|
||||
{actions &&
|
||||
actions.map((action, index) => (
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user