From a4c236b0b05bc7cadf1989138d36b9fb60506d14 Mon Sep 17 00:00:00 2001 From: Deepak Bhagat Date: Fri, 27 Feb 2026 22:26:25 +0530 Subject: [PATCH 1/4] fix: add retry logic to loadThreadMessages to prevent missing thread messages When loadThreadMessages fails (network error, timeout), it silently returns [] causing the thread view to show only a subset of messages. The web client shows all messages correctly for the same thread. This adds retry logic (3 attempts with increasing backoff) and propagates errors to the caller (RoomView.init) which has its own retry mechanism, ensuring thread messages are reliably loaded. --- app/lib/methods/loadThreadMessages.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/lib/methods/loadThreadMessages.ts b/app/lib/methods/loadThreadMessages.ts index 10e568e356b..c8a94f258b7 100644 --- a/app/lib/methods/loadThreadMessages.ts +++ b/app/lib/methods/loadThreadMessages.ts @@ -11,16 +11,24 @@ import { type TThreadMessageModel } from '../../definitions'; import sdk from '../services/sdk'; async function load({ tmid }: { tmid: string }) { - try { - // RC 1.0 - const result = await sdk.methodCallWrapper('getThreadMessages', { tmid }); - if (!result) { - return []; + const MAX_RETRIES = 3; + for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { + try { + // RC 1.0 + const result = await sdk.methodCallWrapper('getThreadMessages', { tmid }); + if (!result) { + return []; + } + return EJSON.fromJSONValue(result); + } catch (e) { + if (attempt < MAX_RETRIES) { + await new Promise(resolve => setTimeout(resolve, attempt * 500)); + } else { + throw e; + } } - return EJSON.fromJSONValue(result); - } catch { - return []; } + return []; } export function loadThreadMessages({ tmid, rid }: { tmid: string; rid: string }) { From 9acd9d4df054083dfdb792c6b4f05317c405a0f7 Mon Sep 17 00:00:00 2001 From: Deepak Bhagat Date: Fri, 27 Feb 2026 22:37:48 +0530 Subject: [PATCH 2/4] refactor: remove unreachable dead code in loadThreadMessages --- app/lib/methods/loadThreadMessages.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/lib/methods/loadThreadMessages.ts b/app/lib/methods/loadThreadMessages.ts index c8a94f258b7..5b67515ce2d 100644 --- a/app/lib/methods/loadThreadMessages.ts +++ b/app/lib/methods/loadThreadMessages.ts @@ -28,7 +28,6 @@ async function load({ tmid }: { tmid: string }) { } } } - return []; } export function loadThreadMessages({ tmid, rid }: { tmid: string; rid: string }) { From bbce023b8bba4c86df17ea3aa8318c4d11592657 Mon Sep 17 00:00:00 2001 From: Deepak Bhagat Date: Fri, 27 Feb 2026 22:52:10 +0530 Subject: [PATCH 3/4] fix: rename MAX_RETRIES to MAX_ATTEMPTS for accurate semantics --- app/lib/methods/loadThreadMessages.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/lib/methods/loadThreadMessages.ts b/app/lib/methods/loadThreadMessages.ts index 5b67515ce2d..481f79f98fc 100644 --- a/app/lib/methods/loadThreadMessages.ts +++ b/app/lib/methods/loadThreadMessages.ts @@ -11,8 +11,9 @@ import { type TThreadMessageModel } from '../../definitions'; import sdk from '../services/sdk'; async function load({ tmid }: { tmid: string }) { - const MAX_RETRIES = 3; - for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { + const MAX_ATTEMPTS = 3; + /* eslint-disable no-await-in-loop */ + for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { try { // RC 1.0 const result = await sdk.methodCallWrapper('getThreadMessages', { tmid }); @@ -21,13 +22,14 @@ async function load({ tmid }: { tmid: string }) { } return EJSON.fromJSONValue(result); } catch (e) { - if (attempt < MAX_RETRIES) { + if (attempt < MAX_ATTEMPTS) { await new Promise(resolve => setTimeout(resolve, attempt * 500)); } else { throw e; } } } + /* eslint-enable no-await-in-loop */ } export function loadThreadMessages({ tmid, rid }: { tmid: string; rid: string }) { From 5e9f927d5bc1cfa8fa364a4fc3b42efe1e1d379e Mon Sep 17 00:00:00 2001 From: Deepak Bhagat Date: Fri, 27 Feb 2026 22:59:18 +0530 Subject: [PATCH 4/4] fix: use 4 total attempts (1 initial + 3 retries) with 500/1000/1500ms backoff --- app/lib/methods/loadThreadMessages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/methods/loadThreadMessages.ts b/app/lib/methods/loadThreadMessages.ts index 481f79f98fc..6c5132b0433 100644 --- a/app/lib/methods/loadThreadMessages.ts +++ b/app/lib/methods/loadThreadMessages.ts @@ -11,7 +11,7 @@ import { type TThreadMessageModel } from '../../definitions'; import sdk from '../services/sdk'; async function load({ tmid }: { tmid: string }) { - const MAX_ATTEMPTS = 3; + const MAX_ATTEMPTS = 4; /* eslint-disable no-await-in-loop */ for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { try {