Add an error boundary around the RoomView

This adds a more specific boundary around the `RoomView` for room-specific
errors and is an example how we could use add boundaries around just a portion
of the app.
This commit is contained in:
J. Ryan Stinnett 2019-10-02 17:28:03 +01:00
parent 0e8dc24c3f
commit b605c0048d

View file

@ -1566,20 +1566,23 @@ module.exports = createReactClass({
const TimelinePanel = sdk.getComponent("structures.TimelinePanel"); const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
const RoomUpgradeWarningBar = sdk.getComponent("rooms.RoomUpgradeWarningBar"); const RoomUpgradeWarningBar = sdk.getComponent("rooms.RoomUpgradeWarningBar");
const RoomRecoveryReminder = sdk.getComponent("rooms.RoomRecoveryReminder"); const RoomRecoveryReminder = sdk.getComponent("rooms.RoomRecoveryReminder");
const ErrorBoundary = sdk.getComponent("elements.ErrorBoundary");
if (!this.state.room) { if (!this.state.room) {
const loading = this.state.roomLoading || this.state.peekLoading; const loading = this.state.roomLoading || this.state.peekLoading;
if (loading) { if (loading) {
return ( return (
<div className="mx_RoomView"> <div className="mx_RoomView">
<RoomPreviewBar <ErrorBoundary>
canPreview={false} <RoomPreviewBar
previewLoading={this.state.peekLoading} canPreview={false}
error={this.state.roomLoadError} previewLoading={this.state.peekLoading}
loading={loading} error={this.state.roomLoadError}
joining={this.state.joining} loading={loading}
oobData={this.props.oobData} joining={this.state.joining}
/> oobData={this.props.oobData}
/>
</ErrorBoundary>
</div> </div>
); );
} else { } else {
@ -1597,18 +1600,20 @@ module.exports = createReactClass({
const roomAlias = this.state.roomAlias; const roomAlias = this.state.roomAlias;
return ( return (
<div className="mx_RoomView"> <div className="mx_RoomView">
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked} <ErrorBoundary>
onForgetClick={this.onForgetClick} <RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
onRejectClick={this.onRejectThreepidInviteButtonClicked} onForgetClick={this.onForgetClick}
canPreview={false} error={this.state.roomLoadError} onRejectClick={this.onRejectThreepidInviteButtonClicked}
roomAlias={roomAlias} canPreview={false} error={this.state.roomLoadError}
joining={this.state.joining} roomAlias={roomAlias}
inviterName={inviterName} joining={this.state.joining}
invitedEmail={invitedEmail} inviterName={inviterName}
oobData={this.props.oobData} invitedEmail={invitedEmail}
signUrl={this.props.thirdPartyInvite ? this.props.thirdPartyInvite.inviteSignUrl : null} oobData={this.props.oobData}
room={this.state.room} signUrl={this.props.thirdPartyInvite ? this.props.thirdPartyInvite.inviteSignUrl : null}
/> room={this.state.room}
/>
</ErrorBoundary>
</div> </div>
); );
} }
@ -1618,12 +1623,14 @@ module.exports = createReactClass({
if (myMembership == 'invite') { if (myMembership == 'invite') {
if (this.state.joining || this.state.rejecting) { if (this.state.joining || this.state.rejecting) {
return ( return (
<RoomPreviewBar <ErrorBoundary>
<RoomPreviewBar
canPreview={false} canPreview={false}
error={this.state.roomLoadError} error={this.state.roomLoadError}
joining={this.state.joining} joining={this.state.joining}
rejecting={this.state.rejecting} rejecting={this.state.rejecting}
/> />
</ErrorBoundary>
); );
} else { } else {
const myUserId = MatrixClientPeg.get().credentials.userId; const myUserId = MatrixClientPeg.get().credentials.userId;
@ -1638,14 +1645,16 @@ module.exports = createReactClass({
// We have a regular invite for this room. // We have a regular invite for this room.
return ( return (
<div className="mx_RoomView"> <div className="mx_RoomView">
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked} <ErrorBoundary>
onForgetClick={this.onForgetClick} <RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
onRejectClick={this.onRejectButtonClicked} onForgetClick={this.onForgetClick}
inviterName={inviterName} onRejectClick={this.onRejectButtonClicked}
canPreview={false} inviterName={inviterName}
joining={this.state.joining} canPreview={false}
room={this.state.room} joining={this.state.joining}
/> room={this.state.room}
/>
</ErrorBoundary>
</div> </div>
); );
} }
@ -1942,41 +1951,43 @@ module.exports = createReactClass({
return ( return (
<main className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref="roomView"> <main className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref="roomView">
<RoomHeader ref="header" room={this.state.room} searchInfo={searchInfo} <ErrorBoundary>
oobData={this.props.oobData} <RoomHeader ref="header" room={this.state.room} searchInfo={searchInfo}
inRoom={myMembership === 'join'} oobData={this.props.oobData}
collapsedRhs={collapsedRhs} inRoom={myMembership === 'join'}
onSearchClick={this.onSearchClick} collapsedRhs={collapsedRhs}
onSettingsClick={this.onSettingsClick} onSearchClick={this.onSearchClick}
onPinnedClick={this.onPinnedClick} onSettingsClick={this.onSettingsClick}
onCancelClick={(aux && !hideCancel) ? this.onCancelClick : null} onPinnedClick={this.onPinnedClick}
onForgetClick={(myMembership === "leave") ? this.onForgetClick : null} onCancelClick={(aux && !hideCancel) ? this.onCancelClick : null}
onLeaveClick={(myMembership === "join") ? this.onLeaveClick : null} onForgetClick={(myMembership === "leave") ? this.onForgetClick : null}
e2eStatus={this.state.e2eStatus} onLeaveClick={(myMembership === "join") ? this.onLeaveClick : null}
/> e2eStatus={this.state.e2eStatus}
<MainSplit />
panel={rightPanel} <MainSplit
collapsedRhs={collapsedRhs} panel={rightPanel}
resizeNotifier={this.props.resizeNotifier} collapsedRhs={collapsedRhs}
> resizeNotifier={this.props.resizeNotifier}
<div className={fadableSectionClasses}> >
{ auxPanel } <div className={fadableSectionClasses}>
<div className="mx_RoomView_timeline"> {auxPanel}
{ topUnreadMessagesBar } <div className="mx_RoomView_timeline">
{ jumpToBottom } {topUnreadMessagesBar}
{ messagePanel } {jumpToBottom}
{ searchResultsPanel } {messagePanel}
</div> {searchResultsPanel}
<div className={statusBarAreaClass}>
<div className="mx_RoomView_statusAreaBox">
<div className="mx_RoomView_statusAreaBox_line"></div>
{ statusBar }
</div> </div>
<div className={statusBarAreaClass}>
<div className="mx_RoomView_statusAreaBox">
<div className="mx_RoomView_statusAreaBox_line"></div>
{statusBar}
</div>
</div>
{previewBar}
{messageComposer}
</div> </div>
{ previewBar } </MainSplit>
{ messageComposer } </ErrorBoundary>
</div>
</MainSplit>
</main> </main>
); );
}, },