fix(core-state): clarify retry failure logs (#2167)

Adds coreStatePollFailureDebugMessage helper to eliminate impossible attempt counters (e.g. 11/5) from debug logs, distinguishing bootstrap retries from post-bootstrap background polling.

Fixes #2158

Co-authored-by: okbexx <okbexx@users.noreply.github.com>
This commit is contained in:
Jarl
2026-05-19 15:36:32 +05:30
committed by GitHub
co-authored by okbexx
parent e2ce0f844c
commit 91a5bb9db9
2 changed files with 34 additions and 6 deletions
+17 -6
View File
@@ -75,6 +75,19 @@ export function coreStatePollFailureWarningMessage(failureCount: number): string
return null;
}
export function coreStatePollFailureDebugMessage(failureCount: number): string | null {
if (failureCount <= 0) {
return null;
}
if (failureCount < MAX_BOOTSTRAP_RETRIES) {
return `refresh failed during bootstrap retry ${failureCount}/${MAX_BOOTSTRAP_RETRIES}; nextAction=retrying`;
}
if (failureCount === MAX_BOOTSTRAP_RETRIES) {
return `refresh failed during bootstrap retry ${failureCount}/${MAX_BOOTSTRAP_RETRIES}; nextAction=marking-ready-with-fallback`;
}
return `refresh failed after ${failureCount} consecutive poll failures; bootstrapRetryLimit=${MAX_BOOTSTRAP_RETRIES}; nextAction=continuing-background-polling-with-warnings-suppressed`;
}
function decodeJwtPayload(token: string): Record<string, unknown> | null {
const [, payload] = token.split('.');
if (!payload) return null;
@@ -425,12 +438,10 @@ export default function CoreStateProvider({ children }: { children: ReactNode })
if (!cancelled) {
bootstrapFailCountRef.current += 1;
const safe = sanitizeError(error);
log(
'refresh failed attempt=%d/%d error=%O',
bootstrapFailCountRef.current,
MAX_BOOTSTRAP_RETRIES,
safe
);
const debugMessage = coreStatePollFailureDebugMessage(bootstrapFailCountRef.current);
if (debugMessage) {
log('%s error=%O', debugMessage, safe);
}
const warningMessage = coreStatePollFailureWarningMessage(bootstrapFailCountRef.current);
if (warningMessage) {
console.warn(warningMessage, safe);
@@ -7,6 +7,7 @@ import * as tauriCommands from '../../utils/tauriCommands';
import { getCoreStateSnapshot, setCoreStateSnapshot } from '../../lib/coreState/store';
import { setActiveUserId } from '../../store/userScopedStorage';
import CoreStateProvider, {
coreStatePollFailureDebugMessage,
coreStatePollFailureWarningMessage,
useCoreState,
} from '../CoreStateProvider';
@@ -524,4 +525,20 @@ describe('coreStatePollFailureWarningMessage', () => {
);
expect(coreStatePollFailureWarningMessage(7)).toBeNull();
});
it('describes post-bootstrap poll failures without impossible retry counters', () => {
expect(coreStatePollFailureDebugMessage(0)).toBeNull();
expect(coreStatePollFailureDebugMessage(1)).toBe(
'refresh failed during bootstrap retry 1/5; nextAction=retrying'
);
expect(coreStatePollFailureDebugMessage(5)).toBe(
'refresh failed during bootstrap retry 5/5; nextAction=marking-ready-with-fallback'
);
const postBootstrapMessage = coreStatePollFailureDebugMessage(11);
expect(postBootstrapMessage).toBe(
'refresh failed after 11 consecutive poll failures; bootstrapRetryLimit=5; nextAction=continuing-background-polling-with-warnings-suppressed'
);
expect(postBootstrapMessage).not.toContain('11/5');
});
});