Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Error resistant data dump from TimelinePanel (#9079)
Browse files Browse the repository at this point in the history
Error resistant data dump from `TimelinePanel` so we still have some data to dump if one of the pieces errors out.

Example error that can happen (as seen in element-hq/element-web-rageshakes#14197):

```
Uncaught TypeError: Cannot read properties of null (reading 'getEvents')
    at TimelineWindow.getEvents (timeline-window.ts:378:37)
    at TimelinePanel_TimelinePanel.onDumpDebugLogs (TimelinePanel.tsx:434:60)
    at Object.ID_727 (TimelinePanel.tsx:609:22)
    at MatrixDispatcher._invokeCallback (Dispatcher.js:198:1)
    at MatrixDispatcher.dispatch (Dispatcher.js:174:1)
    at sentryWrapped (helpers.js:77:1)
```
  • Loading branch information
MadLittleMods authored Jul 22, 2022
1 parent e694e87 commit dfa844a
Showing 1 changed file with 51 additions and 29 deletions.
80 changes: 51 additions & 29 deletions src/components/structures/TimelinePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -384,24 +384,28 @@ class TimelinePanel extends React.Component<IProps, IState> {
* every message change so instead we only log it out when asked.
*/
private onDumpDebugLogs = (): void => {
const room = this.props.timelineSet.room;
const room = this.props.timelineSet?.room;
// Get a list of the event IDs used in this TimelinePanel.
// This includes state and hidden events which we don't render
const eventIdList = this.state.events.map((ev) => ev.getId());
const eventIdList = this.state?.events?.map((ev) => ev.getId());

// Get the list of actually rendered events seen in the DOM.
// This is useful to know for sure what's being shown on screen.
// And we can suss out any corrupted React `key` problems.
let renderedEventIds: string[];
const messagePanel = this.messagePanel.current;
if (messagePanel) {
const messagePanelNode = ReactDOM.findDOMNode(messagePanel) as Element;
if (messagePanelNode) {
const actuallyRenderedEvents = messagePanelNode.querySelectorAll('[data-event-id]');
renderedEventIds = [...actuallyRenderedEvents].map((renderedEvent) => {
return renderedEvent.getAttribute('data-event-id');
});
try {
const messagePanel = this.messagePanel.current;
if (messagePanel) {
const messagePanelNode = ReactDOM.findDOMNode(messagePanel) as Element;
if (messagePanelNode) {
const actuallyRenderedEvents = messagePanelNode.querySelectorAll('[data-event-id]');
renderedEventIds = [...actuallyRenderedEvents].map((renderedEvent) => {
return renderedEvent.getAttribute('data-event-id');
});
}
}
} catch (err) {
logger.error(`onDumpDebugLogs: Failed to get the actual event ID's in the DOM`, err);
}

// Get the list of events and threads for the room as seen by the
Expand All @@ -413,26 +417,44 @@ class TimelinePanel extends React.Component<IProps, IState> {
const timelineSets = room.getTimelineSets();
const threadsTimelineSets = room.threadsTimelineSets;

// Serialize all of the timelineSets and timelines in each set to their event IDs
serializedEventIdsFromTimelineSets = serializeEventIdsFromTimelineSets(timelineSets);
serializedEventIdsFromThreadsTimelineSets = serializeEventIdsFromTimelineSets(threadsTimelineSets);

// Serialize all threads in the room from theadId -> event IDs in the thread
room.getThreads().forEach((thread) => {
serializedThreadsMap[thread.id] = {
events: thread.events.map(ev => ev.getId()),
numTimelines: thread.timelineSet.getTimelines().length,
liveTimeline: thread.timelineSet.getLiveTimeline().getEvents().length,
prevTimeline: thread.timelineSet.getLiveTimeline().getNeighbouringTimeline(Direction.Backward)
?.getEvents().length,
nextTimeline: thread.timelineSet.getLiveTimeline().getNeighbouringTimeline(Direction.Forward)
?.getEvents().length,
};
});
try {
// Serialize all of the timelineSets and timelines in each set to their event IDs
serializedEventIdsFromTimelineSets = serializeEventIdsFromTimelineSets(timelineSets);
serializedEventIdsFromThreadsTimelineSets = serializeEventIdsFromTimelineSets(threadsTimelineSets);
} catch (err) {
logger.error(`onDumpDebugLogs: Failed to serialize event IDs from timelinesets`, err);
}

try {
// Serialize all threads in the room from theadId -> event IDs in the thread
room.getThreads().forEach((thread) => {
serializedThreadsMap[thread.id] = {
events: thread.events.map(ev => ev.getId()),
numTimelines: thread.timelineSet.getTimelines().length,
liveTimeline: thread.timelineSet.getLiveTimeline().getEvents().length,
prevTimeline: thread.timelineSet.getLiveTimeline().getNeighbouringTimeline(Direction.Backward)
?.getEvents().length,
nextTimeline: thread.timelineSet.getLiveTimeline().getNeighbouringTimeline(Direction.Forward)
?.getEvents().length,
};
});
} catch (err) {
logger.error(`onDumpDebugLogs: Failed to serialize event IDs from the threads`, err);
}
}

const timelineWindowEventIds = this.timelineWindow.getEvents().map(ev => ev.getId());
const pendingEvents = this.props.timelineSet.getPendingEvents().map(ev => ev.getId());
let timelineWindowEventIds: string[];
try {
timelineWindowEventIds = this.timelineWindow.getEvents().map(ev => ev.getId());
} catch (err) {
logger.error(`onDumpDebugLogs: Failed to get event IDs from the timelineWindow`, err);
}
let pendingEventIds: string[];
try {
pendingEventIds = this.props.timelineSet.getPendingEvents().map(ev => ev.getId());
} catch (err) {
logger.error(`onDumpDebugLogs: Failed to get pending event IDs`, err);
}

logger.debug(
`TimelinePanel(${this.context.timelineRenderingType}): Debugging info for ${room?.roomId}\n` +
Expand All @@ -444,7 +466,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
`${JSON.stringify(serializedEventIdsFromThreadsTimelineSets)}\n` +
`\tserializedThreadsMap=${JSON.stringify(serializedThreadsMap)}\n` +
`\ttimelineWindowEventIds(${timelineWindowEventIds.length})=${JSON.stringify(timelineWindowEventIds)}\n` +
`\tpendingEvents(${pendingEvents.length})=${JSON.stringify(pendingEvents)}`,
`\tpendingEventIds(${pendingEventIds.length})=${JSON.stringify(pendingEventIds)}`,
);
};

Expand Down

0 comments on commit dfa844a

Please sign in to comment.