Commit 174ee951 by Ivana Huckova Committed by GitHub

Store: Error handling for setObject (#23650)

* Error handling for setObject to store

* Update public/app/core/store.ts

Co-Authored-By: kay delaney <45561153+kaydelaney@users.noreply.github.com>

* Update public/app/features/explore/RichHistory/RichHistory.tsx

Co-Authored-By: kay delaney <45561153+kaydelaney@users.noreply.github.com>

* Move setState outside of try-catch block

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>
parent 4ea41dc1
......@@ -24,7 +24,11 @@ export class LocalStorageValueProvider<T> extends PureComponent<Props<T>, State<
onSaveToStore = (value: T) => {
const { storageKey } = this.props;
store.setObject(storageKey, value);
try {
store.setObject(storageKey, value);
} catch (error) {
console.error(error);
}
this.setState({ value });
};
......
......@@ -29,21 +29,19 @@ export class Store {
return ret;
}
// Returns true when successfully stored
setObject(key: string, value: any): boolean {
/* Returns true when successfully stored, throws error if not successfully stored */
setObject(key: string, value: any) {
let json;
try {
json = JSON.stringify(value);
} catch (error) {
console.error(`Could not stringify object: ${key}. [${error}]`);
return false;
throw new Error(`Could not stringify object: ${key}. [${error}]`);
}
try {
this.set(key, json);
} catch (error) {
// Likely hitting storage quota
console.error(`Could not save item in localStorage: ${key}. [${error}]`);
return false;
throw new Error(`Could not save item in localStorage: ${key}. [${error}]`);
}
return true;
}
......
......@@ -345,18 +345,24 @@ export function updateHistory<T extends DataQuery = any>(
queries: T[]
): Array<HistoryItem<T>> {
const ts = Date.now();
let updatedHistory = history;
queries.forEach(query => {
history = [{ query, ts }, ...history];
updatedHistory = [{ query, ts }, ...updatedHistory];
});
if (history.length > MAX_HISTORY_ITEMS) {
history = history.slice(0, MAX_HISTORY_ITEMS);
if (updatedHistory.length > MAX_HISTORY_ITEMS) {
updatedHistory = updatedHistory.slice(0, MAX_HISTORY_ITEMS);
}
// Combine all queries of a datasource type into one history
const historyKey = `grafana.explore.history.${datasourceId}`;
store.setObject(historyKey, history);
return history;
try {
store.setObject(historyKey, updatedHistory);
return updatedHistory;
} catch (error) {
console.error(error);
return history;
}
}
export function clearHistory(datasourceId: string) {
......
......@@ -2,7 +2,8 @@
import _ from 'lodash';
// Services & Utils
import { DataQuery, ExploreMode, dateTime, urlUtil } from '@grafana/data';
import { DataQuery, ExploreMode, dateTime, AppEvents, urlUtil } from '@grafana/data';
import appEvents from 'app/core/app_events';
import store from 'app/core/store';
import { serializeStateToUrlParam, SortOrder } from './explore';
import { getExploreDatasources } from '../../features/explore/state/selectors';
......@@ -55,18 +56,17 @@ export function addToRichHistory(
return richHistory;
}
let newHistory = [
let updatedHistory = [
{ queries: queriesToSave, ts, datasourceId, datasourceName, starred, comment, sessionName },
...queriesToKeep,
];
/* Combine all queries of a datasource type into one rich history */
const isSaved = store.setObject(RICH_HISTORY_KEY, newHistory);
/* If newHistory is succesfully saved, return it. Otherwise return not updated richHistory. */
if (isSaved) {
return newHistory;
} else {
/* If updatedHistory is succesfully saved, return it. Otherwise return not updated richHistory. */
try {
store.setObject(RICH_HISTORY_KEY, updatedHistory);
return updatedHistory;
} catch (error) {
appEvents.emit(AppEvents.alertError, [error]);
return richHistory;
}
}
......@@ -83,7 +83,7 @@ export function deleteAllFromRichHistory() {
}
export function updateStarredInRichHistory(richHistory: RichHistoryQuery[], ts: number) {
const updatedQueries = richHistory.map(query => {
const updatedHistory = richHistory.map(query => {
/* Timestamps are currently unique - we can use them to identify specific queries */
if (query.ts === ts) {
const isStarred = query.starred;
......@@ -93,8 +93,13 @@ export function updateStarredInRichHistory(richHistory: RichHistoryQuery[], ts:
return query;
});
store.setObject(RICH_HISTORY_KEY, updatedQueries);
return updatedQueries;
try {
store.setObject(RICH_HISTORY_KEY, updatedHistory);
return updatedHistory;
} catch (error) {
appEvents.emit(AppEvents.alertError, [error]);
return richHistory;
}
}
export function updateCommentInRichHistory(
......@@ -102,7 +107,7 @@ export function updateCommentInRichHistory(
ts: number,
newComment: string | undefined
) {
const updatedQueries = richHistory.map(query => {
const updatedHistory = richHistory.map(query => {
if (query.ts === ts) {
const updatedQuery = Object.assign({}, query, { comment: newComment });
return updatedQuery;
......@@ -110,14 +115,24 @@ export function updateCommentInRichHistory(
return query;
});
store.setObject(RICH_HISTORY_KEY, updatedQueries);
return updatedQueries;
try {
store.setObject(RICH_HISTORY_KEY, updatedHistory);
return updatedHistory;
} catch (error) {
appEvents.emit(AppEvents.alertError, [error]);
return richHistory;
}
}
export function deleteQueryInRichHistory(richHistory: RichHistoryQuery[], ts: number) {
const updatedQueries = richHistory.filter(query => query.ts !== ts);
store.setObject(RICH_HISTORY_KEY, updatedQueries);
return updatedQueries;
const updatedHistory = richHistory.filter(query => query.ts !== ts);
try {
store.setObject(RICH_HISTORY_KEY, updatedHistory);
return updatedHistory;
} catch (error) {
appEvents.emit(AppEvents.alertError, [error]);
return richHistory;
}
}
export const sortQueries = (array: RichHistoryQuery[], sortOrder: SortOrder) => {
......
......@@ -78,6 +78,10 @@ export function updatePanelEditorUIState(uiState: Partial<PanelEditorUIState>):
return (dispatch, getStore) => {
const nextState = { ...getStore().panelEditor.ui, ...uiState };
dispatch(setPanelEditorUIState(nextState));
store.setObject(PANEL_EDITOR_UI_STATE_STORAGE_KEY, nextState);
try {
store.setObject(PANEL_EDITOR_UI_STATE_STORAGE_KEY, nextState);
} catch (error) {
console.error(error);
}
};
}
......@@ -114,7 +114,14 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
};
onSelectDatasourceFilters = (value: SelectableValue[] | null) => {
store.setObject(RICH_HISTORY_SETTING_KEYS.datasourceFilters, value);
try {
store.setObject(RICH_HISTORY_SETTING_KEYS.datasourceFilters, value);
} catch (error) {
console.error(error);
}
/* Set data source filters to state even though they were not successfully saved in
* localStorage to allow interaction and filtering.
**/
this.setState({ datasourceFilters: value });
};
......@@ -125,7 +132,7 @@ class UnThemedRichHistory extends PureComponent<RichHistoryProps, RichHistorySta
onChangeSortOrder = (sortOrder: SortOrder) => this.setState({ sortOrder });
/* If user selects activeDatasourceOnly === true, set datasource filter to currently active datasource.
* Filtering based on datasource won't be available. Otherwise set to null, as filtering will be
* Filtering based on datasource won't be available. Otherwise set to null, as filtering will be
* available for user.
*/
updateFilters() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment