Add a devtool button to mock an error

This commit is contained in:
Timo K.
2026-10-14 11:36:54 +02:00
parent 4b73ce68e3
commit f60a63e20c
4 changed files with 75 additions and 0 deletions
+1
View File
@@ -88,6 +88,7 @@
},
"mute_all_audio": "Mute all audio (participants, reactions, join sounds)",
"show_connection_stats": "Show connection statistics",
"throw_error_button": "Throw test error",
"url_params": "URL parameters"
},
"disconnected_banner": "Connectivity to the server has been lost.",
@@ -30,6 +30,9 @@ import {
} from "@element-hq/matrixrtc-sdk";
import type * as MatrixRTCSdk from "@element-hq/matrixrtc-sdk";
import { exampleTransport, mockConfig } from "../utils/test";
import { GroupCallErrorBoundary } from "../room/GroupCallErrorBoundary";
import { LeaveToHomeProvider } from "../LeaveToHomeContext";
import { ElementCallError, ErrorCode } from "../utils/errors";
// Mock url params hook to avoid environment-dependent snapshot churn.
vi.mock("../UrlParams", () => ({
@@ -493,4 +496,38 @@ describe("DeveloperSettingsTab", () => {
);
});
});
describe("throw test error", () => {
it("throws an ElementCallError that the error boundary shows", async () => {
const user = userEvent.setup();
const client = createMockMatrixClient();
const onError = vi.fn();
render(
<LeaveToHomeProvider value={vi.fn()}>
<GroupCallErrorBoundary
onError={onError}
recoveryActionHandler={vi.fn()}
>
<TooltipProvider>
<DeveloperSettingsTab
client={client}
env={{} as unknown as ImportMetaEnv}
vm={outOfCallDeveloperSettingsTabViewModel}
/>
</TooltipProvider>
</GroupCallErrorBoundary>
</LeaveToHomeProvider>,
);
await user.click(
screen.getByRole("button", { name: "Throw test error" }),
);
expect(await screen.findByText("Something went wrong")).toBeVisible();
expect(onError).toHaveBeenCalledOnce();
const error = onError.mock.calls[0][0] as unknown;
expect(error).toBeInstanceOf(ElementCallError);
expect((error as ElementCallError).code).toBe(ErrorCode.UNKNOWN_ERROR);
});
});
});
+22
View File
@@ -22,6 +22,7 @@ import {
import { logger } from "matrix-js-sdk/lib/logger";
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
import {
Button,
EditInPlace,
ErrorMessage,
Root as Form,
@@ -72,6 +73,7 @@ import {
} from "@element-hq/matrixrtc-sdk";
import { useBehavior } from "../useBehavior";
import { type ViewModel } from "../state/ViewModel.ts";
import { type ElementCallError, UnknownCallError } from "../utils/errors.ts";
/**
* The state of MatrixRTC's media key rotation.
@@ -189,6 +191,22 @@ export const DeveloperSettingsTab: FC<Props> = ({
const urlParams = useUrlParams();
// An error thrown from a click handler never reaches an error boundary, so
// the button only records it and the next render throws it instead.
const [errorToThrow, setErrorToThrow] = useState<ElementCallError | null>(
null,
);
const throwTestError = useCallback(
() =>
setErrorToThrow(
new UnknownCallError(
new Error("Test error thrown from the developer settings"),
),
),
[],
);
if (errorToThrow !== null) throw errorToThrow;
const MediaQualitySettings: React.FC<{
id: string;
header: string;
@@ -649,6 +667,10 @@ export const DeveloperSettingsTab: FC<Props> = ({
<Separator />
<AudioProcessingSettings />
<Separator />
<Button kind="secondary" destructive onClick={throwTestError}>
{t("developer_mode.throw_error_button")}
</Button>
<Separator />
<p>{t("developer_mode.environment_variables")}</p>
<pre className={styles.pre}>{JSON.stringify(env, null, 2)}</pre>
<p>{t("developer_mode.url_params")}</p>
@@ -635,6 +635,21 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = `
data-orientation="horizontal"
role="separator"
/>
<button
class="_button_1nw83_8 _destructive_1nw83_110"
data-kind="secondary"
data-size="lg"
role="button"
tabindex="0"
>
Throw test error
</button>
<div
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
/>
<p>
Environment variables
</p>