mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-10 21:55:19 +00:00
Catch the component's errors inside the component
Only the call body sat inside an error boundary; anything thrown in the lobby, the mute state or the providers propagated into the host's React tree, where React unmounts everything up to the nearest boundary — the host's, or the host's whole application. The standalone app has a boundary at its top; the component now has the same, showing the error page inside its container and asking the host to stop keeping it on screen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
779ee7a008
commit
d18e82c546
+28
-18
@@ -45,11 +45,13 @@ import { logger } from "matrix-js-sdk/lib/logger";
|
|||||||
import { MemoryRouter } from "react-router-dom";
|
import { MemoryRouter } from "react-router-dom";
|
||||||
import { I18nextProvider } from "react-i18next";
|
import { I18nextProvider } from "react-i18next";
|
||||||
import { TooltipProvider } from "@vector-im/compound-web";
|
import { TooltipProvider } from "@vector-im/compound-web";
|
||||||
|
import { ErrorBoundary } from "@sentry/react";
|
||||||
import { shouldPolyfill as shouldPolyfillSegmenter } from "@formatjs/intl-segmenter/should-polyfill";
|
import { shouldPolyfill as shouldPolyfillSegmenter } from "@formatjs/intl-segmenter/should-polyfill";
|
||||||
import { shouldPolyfill as shouldPolyfillDurationFormat } from "@formatjs/intl-durationformat/should-polyfill.js";
|
import { shouldPolyfill as shouldPolyfillDurationFormat } from "@formatjs/intl-durationformat/should-polyfill.js";
|
||||||
|
|
||||||
import EN from "../locales/en/app.json";
|
import EN from "../locales/en/app.json";
|
||||||
import { ElementCallView } from "../src/ElementCallView";
|
import { ElementCallView } from "../src/ElementCallView";
|
||||||
|
import { ErrorPage } from "../src/FullScreenView";
|
||||||
import { ClientProvider } from "../src/ClientContext";
|
import { ClientProvider } from "../src/ClientContext";
|
||||||
import {
|
import {
|
||||||
type HostBridge,
|
type HostBridge,
|
||||||
@@ -265,24 +267,32 @@ export const ElementCall: FC<ElementCallProps> = ({
|
|||||||
rtcSession !== null &&
|
rtcSession !== null &&
|
||||||
mediaDevices !== null && (
|
mediaDevices !== null && (
|
||||||
<RootElementProvider value={container}>
|
<RootElementProvider value={container}>
|
||||||
<Decoration>
|
{/* Whatever goes wrong in here is shown in here. Left to
|
||||||
<TooltipProvider>
|
propagate, an error would unmount the host's own tree. */}
|
||||||
<ClientProvider client={client}>
|
<ErrorBoundary
|
||||||
<MediaDevicesContext value={mediaDevices}>
|
fallback={(error) => <ErrorPage error={error} />}
|
||||||
<ProcessorProvider>
|
// A broken call should not hold the host on screen
|
||||||
<ElementCallView
|
onError={() => void hostBridge.setAlwaysOnScreen(false)}
|
||||||
client={client}
|
>
|
||||||
rtcSession={rtcSession}
|
<Decoration>
|
||||||
isPasswordlessUser={false}
|
<TooltipProvider>
|
||||||
confineToRoom={params.confineToRoom}
|
<ClientProvider client={client}>
|
||||||
preload={params.preload}
|
<MediaDevicesContext value={mediaDevices}>
|
||||||
skipLobby={params.skipLobby}
|
<ProcessorProvider>
|
||||||
/>
|
<ElementCallView
|
||||||
</ProcessorProvider>
|
client={client}
|
||||||
</MediaDevicesContext>
|
rtcSession={rtcSession}
|
||||||
</ClientProvider>
|
isPasswordlessUser={false}
|
||||||
</TooltipProvider>
|
confineToRoom={params.confineToRoom}
|
||||||
</Decoration>
|
preload={params.preload}
|
||||||
|
skipLobby={params.skipLobby}
|
||||||
|
/>
|
||||||
|
</ProcessorProvider>
|
||||||
|
</MediaDevicesContext>
|
||||||
|
</ClientProvider>
|
||||||
|
</TooltipProvider>
|
||||||
|
</Decoration>
|
||||||
|
</ErrorBoundary>
|
||||||
</RootElementProvider>
|
</RootElementProvider>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user