diff --git a/src/matrix/room/timeline/FragmentIdComparer.js b/src/matrix/room/timeline/FragmentIdComparer.js index 2c829418..fcd27edf 100644 --- a/src/matrix/room/timeline/FragmentIdComparer.js +++ b/src/matrix/room/timeline/FragmentIdComparer.js @@ -127,6 +127,10 @@ class Island { } } +export class CompareError extends Error { + get name() { return "CompareError"; } +} + /* index for fast lookup of how two fragments can be sorted */ @@ -139,7 +143,7 @@ export class FragmentIdComparer { _getIsland(id) { const island = this._idToIsland.get(id); if (island === undefined) { - throw new Error(`Unknown fragment id ${id}`); + throw new CompareError(`Unknown fragment id ${id}`); } return island; } @@ -151,7 +155,7 @@ export class FragmentIdComparer { const islandA = this._getIsland(idA); const islandB = this._getIsland(idB); if (islandA !== islandB) { - throw new Error(`${idA} and ${idB} are on different islands, can't tell order`); + throw new CompareError(`${idA} and ${idB} are on different islands, can't tell order`); } return islandA.compare(idA, idB); } diff --git a/src/matrix/room/timeline/Timeline.js b/src/matrix/room/timeline/Timeline.js index bd521e62..fdfaee48 100644 --- a/src/matrix/room/timeline/Timeline.js +++ b/src/matrix/room/timeline/Timeline.js @@ -212,7 +212,22 @@ export class Timeline { replaceEntries(entries) { this._addLocalRelationsToNewRemoteEntries(entries); for (const entry of entries) { - this._remoteEntries.getAndUpdate(entry, Timeline._entryUpdater); + try { + this._remoteEntries.getAndUpdate(entry, Timeline._entryUpdater); + } catch (err) { + if (err.name === "CompareError") { + // see FragmentIdComparer, if the replacing entry is on a fragment + // that is currently not loaded into the FragmentIdComparer, it will + // throw a CompareError, and it means that the event is not loaded + // in the timeline (like when receiving a relation for an event + // that is not loaded in memory) so we can just drop this error as + // replacing an event that is not already loaded is a no-op. + continue; + } else { + // don't swallow other errors + throw err; + } + } } }