Wrap all EventTiles with a TileErrorBoundary and guard parsePermalink (#7916)

Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
Michael Telatynski 2022-03-01 08:41:48 +00:00 committed by GitHub
parent 08c47ac473
commit 16e67e7716
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 40 deletions

View file

@ -48,7 +48,6 @@ import DateSeparator from '../views/messages/DateSeparator';
import ErrorBoundary from '../views/elements/ErrorBoundary'; import ErrorBoundary from '../views/elements/ErrorBoundary';
import ResizeNotifier from "../../utils/ResizeNotifier"; import ResizeNotifier from "../../utils/ResizeNotifier";
import Spinner from "../views/elements/Spinner"; import Spinner from "../views/elements/Spinner";
import TileErrorBoundary from '../views/messages/TileErrorBoundary';
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import EditorStateTransfer from "../../utils/EditorStateTransfer"; import EditorStateTransfer from "../../utils/EditorStateTransfer";
import { Action } from '../../dispatcher/actions'; import { Action } from '../../dispatcher/actions';
@ -787,8 +786,8 @@ export default class MessagePanel extends React.Component<IProps, IState> {
const callEventGrouper = this.props.callEventGroupers.get(mxEv.getContent().call_id); const callEventGrouper = this.props.callEventGroupers.get(mxEv.getContent().call_id);
// use txnId as key if available so that we don't remount during sending // use txnId as key if available so that we don't remount during sending
ret.push( ret.push(
<TileErrorBoundary key={mxEv.getTxnId() || eventId} mxEvent={mxEv} layout={this.props.layout}>
<EventTile <EventTile
key={mxEv.getTxnId() || eventId}
as="li" as="li"
ref={this.collectEventTile.bind(this, eventId)} ref={this.collectEventTile.bind(this, eventId)}
alwaysShowTimestamps={this.props.alwaysShowTimestamps} alwaysShowTimestamps={this.props.alwaysShowTimestamps}
@ -816,8 +815,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
showReadReceipts={this.props.showReadReceipts} showReadReceipts={this.props.showReadReceipts}
callEventGrouper={callEventGrouper} callEventGrouper={callEventGrouper}
hideSender={this.state.hideSender} hideSender={this.state.hideSender}
/> />,
</TileErrorBoundary>,
); );
return ret; return ret;

View file

@ -82,6 +82,7 @@ import RedactedBody from '../messages/RedactedBody';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { shouldDisplayReply } from '../../../utils/Reply'; import { shouldDisplayReply } from '../../../utils/Reply';
import PosthogTrackers from "../../../PosthogTrackers"; import PosthogTrackers from "../../../PosthogTrackers";
import TileErrorBoundary from '../messages/TileErrorBoundary';
export type GetRelationsForEvent = (eventId: string, relationType: string, eventType: string) => Relations; export type GetRelationsForEvent = (eventId: string, relationType: string, eventType: string) => Relations;
@ -1114,7 +1115,7 @@ export default class EventTile extends React.Component<IProps, IState> {
return false; return false;
} }
render() { private renderEvent() {
const msgtype = this.props.mxEvent.getContent().msgtype; const msgtype = this.props.mxEvent.getContent().msgtype;
const eventType = this.props.mxEvent.getType() as EventType; const eventType = this.props.mxEvent.getType() as EventType;
const { const {
@ -1641,6 +1642,12 @@ export default class EventTile extends React.Component<IProps, IState> {
} }
} }
} }
public render() {
return <TileErrorBoundary mxEvent={this.props.mxEvent} layout={this.props.layout}>
{ this.renderEvent() }
</TileErrorBoundary>;
}
} }
// XXX this'll eventually be dynamic based on the fields once we have extensible event types // XXX this'll eventually be dynamic based on the fields once we have extensible event types

View file

@ -422,6 +422,7 @@ function getPermalinkConstructor(): PermalinkConstructor {
} }
export function parsePermalink(fullUrl: string): PermalinkParts { export function parsePermalink(fullUrl: string): PermalinkParts {
try {
const elementPrefix = SdkConfig.get()['permalinkPrefix']; const elementPrefix = SdkConfig.get()['permalinkPrefix'];
if (decodeURIComponent(fullUrl).startsWith(matrixtoBaseUrl)) { if (decodeURIComponent(fullUrl).startsWith(matrixtoBaseUrl)) {
return new MatrixToPermalinkConstructor().parsePermalink(decodeURIComponent(fullUrl)); return new MatrixToPermalinkConstructor().parsePermalink(decodeURIComponent(fullUrl));
@ -430,6 +431,9 @@ export function parsePermalink(fullUrl: string): PermalinkParts {
} else if (elementPrefix && fullUrl.startsWith(elementPrefix)) { } else if (elementPrefix && fullUrl.startsWith(elementPrefix)) {
return new ElementPermalinkConstructor(elementPrefix).parsePermalink(fullUrl); return new ElementPermalinkConstructor(elementPrefix).parsePermalink(fullUrl);
} }
} catch (e) {
logger.error("Failed to parse permalink", e);
}
return null; // not a permalink we can handle return null; // not a permalink we can handle
} }