Query History: Track query history migration failures (#49560)

This commit is contained in:
Piotr Jamróz 2022-05-25 12:21:23 +02:00 committed by GitHub
parent f93ad85b08
commit a67add5239
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 10 deletions

View File

@ -15,6 +15,7 @@ import {
deleteQueryInRichHistory,
migrateQueryHistoryFromLocalStorage,
SortOrder,
LocalStorageMigrationStatus,
} from './richHistory';
const richHistoryStorageMock: RichHistoryStorage = {} as RichHistoryStorage;
@ -187,13 +188,23 @@ describe('richHistory', () => {
const history = { richHistory: [{ id: 'test' }, { id: 'test2' }], total: 2 };
richHistoryLocalStorageMock.getRichHistory.mockReturnValue(history);
await migrateQueryHistoryFromLocalStorage();
const migrationResult = await migrateQueryHistoryFromLocalStorage();
expect(richHistoryRemoteStorageMock.migrate).toBeCalledWith(history.richHistory);
expect(migrationResult.status).toBe(LocalStorageMigrationStatus.Successful);
expect(migrationResult.error).toBeUndefined();
});
it('does not migrate if there are no entries', async () => {
richHistoryLocalStorageMock.getRichHistory.mockReturnValue([]);
await migrateQueryHistoryFromLocalStorage();
richHistoryLocalStorageMock.getRichHistory.mockReturnValue({ richHistory: [] });
const migrationResult = await migrateQueryHistoryFromLocalStorage();
expect(richHistoryRemoteStorageMock.migrate).not.toBeCalled();
expect(migrationResult.status).toBe(LocalStorageMigrationStatus.NotNeeded);
expect(migrationResult.error).toBeUndefined();
});
it('propagates thrown errors', async () => {
richHistoryLocalStorageMock.getRichHistory.mockRejectedValue(new Error('migration failed'));
const migrationResult = await migrateQueryHistoryFromLocalStorage();
expect(migrationResult.status).toBe(LocalStorageMigrationStatus.Failed);
expect(migrationResult.error?.message).toBe('migration failed');
});
});

View File

@ -131,7 +131,12 @@ export enum LocalStorageMigrationStatus {
NotNeeded = 'not-needed',
}
export async function migrateQueryHistoryFromLocalStorage(): Promise<LocalStorageMigrationStatus> {
export interface LocalStorageMigrationResult {
status: LocalStorageMigrationStatus;
error?: Error;
}
export async function migrateQueryHistoryFromLocalStorage(): Promise<LocalStorageMigrationResult> {
const richHistoryLocalStorage = new RichHistoryLocalStorage();
const richHistoryRemoteStorage = new RichHistoryRemoteStorage();
@ -145,14 +150,14 @@ export async function migrateQueryHistoryFromLocalStorage(): Promise<LocalStorag
to: 14,
});
if (richHistory.length === 0) {
return LocalStorageMigrationStatus.NotNeeded;
return { status: LocalStorageMigrationStatus.NotNeeded };
}
await richHistoryRemoteStorage.migrate(richHistory);
dispatch(notifyApp(createSuccessNotification('Query history successfully migrated from local storage')));
return LocalStorageMigrationStatus.Successful;
return { status: LocalStorageMigrationStatus.Successful };
} catch (error) {
dispatch(notifyApp(createWarningNotification(`Query history migration failed. ${error.message}`)));
return LocalStorageMigrationStatus.Failed;
return { status: LocalStorageMigrationStatus.Failed, error };
}
}

View File

@ -1,7 +1,7 @@
import { AnyAction, createAction } from '@reduxjs/toolkit';
import { DataQuery, HistoryItem } from '@grafana/data';
import { config } from '@grafana/runtime';
import { config, logError } from '@grafana/runtime';
import { RICH_HISTORY_SETTING_KEYS } from 'app/core/history/richHistoryLocalStorageUtils';
import store from 'app/core/store';
import {
@ -178,9 +178,10 @@ export const initRichHistory = (): ThunkResult<void> => {
// the migration attempt happens only once per session, and the user is informed about the failure
// in a way that can help with potential investigation.
if (config.queryHistoryEnabled && !queriesMigrated && !migrationFailedDuringThisSession) {
const migrationStatus = await migrateQueryHistoryFromLocalStorage();
if (migrationStatus === LocalStorageMigrationStatus.Failed) {
const migrationResult = await migrateQueryHistoryFromLocalStorage();
if (migrationResult.status === LocalStorageMigrationStatus.Failed) {
dispatch(richHistoryMigrationFailedAction());
logError(migrationResult.error!, { explore: { event: 'QueryHistoryMigrationFailed' } });
} else {
store.set(RICH_HISTORY_SETTING_KEYS.migrated, true);
}