diff --git a/public/app/core/history/RichHistoryLocalStorage.test.ts b/public/app/core/history/RichHistoryLocalStorage.test.ts index a64aee332f0..2d87fb3a185 100644 --- a/public/app/core/history/RichHistoryLocalStorage.test.ts +++ b/public/app/core/history/RichHistoryLocalStorage.test.ts @@ -83,6 +83,8 @@ describe('RichHistoryLocalStorage', () => { jest.setSystemTime(now); storage = new RichHistoryLocalStorage(); await storage.deleteAll(); + + (loggerMock.logWarning as jest.Mock).mockReset(); }); afterEach(() => { @@ -302,13 +304,14 @@ describe('RichHistoryLocalStorage', () => { }) ).rejects.toMatchObject({ name: 'StorageFull' }); - // 3 tracking attempts should be logged (for each failed try) - expect(loggerMock.logWarning).toHaveBeenCalledTimes(3); + // 4 failed tracking attempts (1 save + 3 retries) should be logged (for each failed try) + expect(loggerMock.logWarning).toHaveBeenCalledTimes(4); const calls = (loggerMock.logWarning as jest.Mock).mock.calls; expect(calls[0][0]).toContain('Failed to save rich history to local storage'); expect(calls[0][1].saveRetriesLeft).toBe('3'); expect(calls[1][1].saveRetriesLeft).toBe('2'); expect(calls[2][1].saveRetriesLeft).toBe('1'); + expect(calls[3][1].saveRetriesLeft).toBe('0'); setSpy.mockRestore(); }); diff --git a/public/app/core/history/RichHistoryLocalStorage.ts b/public/app/core/history/RichHistoryLocalStorage.ts index c1471fcdc63..2dedec90665 100644 --- a/public/app/core/history/RichHistoryLocalStorage.ts +++ b/public/app/core/history/RichHistoryLocalStorage.ts @@ -86,7 +86,7 @@ export default class RichHistoryLocalStorage implements RichHistoryStorage { throw error; } - const { queriesToKeep, limitExceeded } = cleanUpUnstarredQuery(currentRichHistoryDTOs, MAX_HISTORY_ITEMS); + let { queriesToKeep, limitExceeded } = cleanUpUnstarredQuery(currentRichHistoryDTOs, MAX_HISTORY_ITEMS); let updatedHistory: RichHistoryLocalStorageDTO[] = [newRichHistoryQueryDTO, ...queriesToKeep]; @@ -98,16 +98,17 @@ export default class RichHistoryLocalStorage implements RichHistoryStorage { store.setObject(RICH_HISTORY_KEY, updatedHistory); saved = true; } catch (error) { - if (saveRetriesLeft >= 1) { - await this.trackLocalStorageUsage('Failed to save rich history to local storage', { - saveRetriesLeft: saveRetriesLeft.toString(), - quotaExceededError: error instanceof Error && error.name === 'QuotaExceededError' ? 'true' : 'false', - errorMessage: error instanceof Error ? error?.message : 'unknown', - }); + await this.trackLocalStorageUsage('Failed to save rich history to local storage', { + saveRetriesLeft: saveRetriesLeft.toString(), + quotaExceededError: error instanceof Error && error.name === 'QuotaExceededError' ? 'true' : 'false', + errorMessage: error instanceof Error ? error?.message : 'unknown', + }); + if (saveRetriesLeft >= 1) { saveRetriesLeft--; - const { queriesToKeep } = cleanUpUnstarredQuery(updatedHistory, updatedHistory.length - 1); - updatedHistory = queriesToKeep; + const { queriesToKeep: newQueriesToKeep } = cleanUpUnstarredQuery(queriesToKeep, queriesToKeep.length - 1); + updatedHistory = [newRichHistoryQueryDTO, ...newQueriesToKeep]; + queriesToKeep = newQueriesToKeep; continue; } @@ -255,7 +256,7 @@ export function cleanUpUnstarredQuery( // remove oldest non-starred items to give space for the recent query let limitExceeded = false; let current = queriesToKeep.length - 1; - while (current >= 0 && queriesToKeep.length > max) { + while (current >= 0 && queriesToKeep.length >= max) { if (!queriesToKeep[current].starred) { queriesToKeep.splice(current, 1); limitExceeded = true;