Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(window): unavailable localStorage and sessionStorage #25599

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 49 additions & 45 deletions superset-frontend/src/SqlLab/reducers/getInitialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,53 +137,57 @@ export default function getInitialState({
* hasn't used SQL Lab after it has been turned on, the state will be stored
* in the browser's local storage.
*/
const localStorageData = localStorage.getItem('redux');
const sqlLabCacheData = localStorageData
? (JSON.parse(localStorageData) as Pick<SqlLabRootState, 'sqlLab'>)
: undefined;
if (localStorageData && sqlLabCacheData?.sqlLab) {
const { sqlLab } = sqlLabCacheData;
try {
const localStorageData = localStorage.getItem('redux');
const sqlLabCacheData = localStorageData
? (JSON.parse(localStorageData) as Pick<SqlLabRootState, 'sqlLab'>)
: undefined;
if (localStorageData && sqlLabCacheData?.sqlLab) {
const { sqlLab } = sqlLabCacheData;

if (sqlLab.queryEditors.length === 0) {
// migration was successful
localStorage.removeItem('redux');
} else {
unsavedQueryEditor = sqlLab.unsavedQueryEditor || unsavedQueryEditor;
// add query editors and tables to state with a special flag so they can
// be migrated if the `SQLLAB_BACKEND_PERSISTENCE` feature flag is on
sqlLab.queryEditors.forEach(qe => {
queryEditors = {
...queryEditors,
[qe.id]: {
...queryEditors[qe.id],
...qe,
name: qe.title || qe.name,
...(unsavedQueryEditor.id === qe.id && unsavedQueryEditor),
inLocalStorage: true,
loaded: true,
},
};
});
const expandedTables = new Set();
tables = sqlLab.tables.reduce((merged, table) => {
const expanded = !expandedTables.has(table.queryEditorId);
if (expanded) {
expandedTables.add(table.queryEditorId);
}
return {
...merged,
[table.id]: {
...tables[table.id],
...table,
expanded,
},
};
}, tables);
Object.values(sqlLab.queries).forEach(query => {
queries[query.id] = { ...query, inLocalStorage: true };
});
tabHistory.push(...sqlLab.tabHistory);
if (sqlLab.queryEditors.length === 0) {
// migration was successful
localStorage.removeItem('redux');
} else {
unsavedQueryEditor = sqlLab.unsavedQueryEditor || unsavedQueryEditor;
// add query editors and tables to state with a special flag so they can
// be migrated if the `SQLLAB_BACKEND_PERSISTENCE` feature flag is on
sqlLab.queryEditors.forEach(qe => {
queryEditors = {
...queryEditors,
[qe.id]: {
...queryEditors[qe.id],
...qe,
name: qe.title || qe.name,
...(unsavedQueryEditor.id === qe.id && unsavedQueryEditor),
inLocalStorage: true,
loaded: true,
},
};
});
const expandedTables = new Set();
tables = sqlLab.tables.reduce((merged, table) => {
const expanded = !expandedTables.has(table.queryEditorId);
if (expanded) {
expandedTables.add(table.queryEditorId);
}
return {
...merged,
[table.id]: {
...tables[table.id],
...table,
expanded,
},
};
}, tables);
Object.values(sqlLab.queries).forEach(query => {
queries[query.id] = { ...query, inLocalStorage: true };
});
tabHistory.push(...sqlLab.tabHistory);
}
}
} catch (error) {
// continue regardless of error
}

return {
Expand Down
49 changes: 30 additions & 19 deletions superset-frontend/src/SqlLab/reducers/sqlLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,16 @@ export default function sqlLabReducer(state = {}, action) {
return { ...state, activeSouthPaneTab: action.tabId };
},
[actions.MIGRATE_QUERY_EDITOR]() {
// remove migrated query editor from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.queryEditors = sqlLab.queryEditors.filter(
qe => qe.id !== action.oldQueryEditor.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));

try {
// remove migrated query editor from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.queryEditors = sqlLab.queryEditors.filter(
qe => qe.id !== action.oldQueryEditor.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
} catch (error) {
// continue regardless of error
}
// replace localStorage query editor with the server backed one
return addToArr(
removeFromArr(state, 'queryEditors', action.oldQueryEditor),
Expand All @@ -438,12 +441,16 @@ export default function sqlLabReducer(state = {}, action) {
);
},
[actions.MIGRATE_TABLE]() {
// remove migrated table from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tables = sqlLab.tables.filter(
table => table.id !== action.oldTable.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
try {
// remove migrated table from localStorage
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tables = sqlLab.tables.filter(
table => table.id !== action.oldTable.id,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
} catch (error) {
// continue regardless of error
}

// replace localStorage table with the server backed one
return addToArr(
Expand All @@ -453,12 +460,16 @@ export default function sqlLabReducer(state = {}, action) {
);
},
[actions.MIGRATE_TAB_HISTORY]() {
// remove migrated tab from localStorage tabHistory
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tabHistory = sqlLab.tabHistory.filter(
tabId => tabId !== action.oldId,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
try {
// remove migrated tab from localStorage tabHistory
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
sqlLab.tabHistory = sqlLab.tabHistory.filter(
tabId => tabId !== action.oldId,
);
localStorage.setItem('redux', JSON.stringify({ sqlLab }));
} catch (error) {
// continue regardless of error
}
const tabHistory = state.tabHistory.filter(
tabId => tabId !== action.oldId,
);
Expand Down
14 changes: 12 additions & 2 deletions superset-frontend/src/explore/components/DatasourcePanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,11 @@ export default function DataSourcePanel({
);

const showInfoboxCheck = () => {
if (sessionStorage.getItem('showInfobox') === 'false') return false;
try {
if (sessionStorage.getItem('showInfobox') === 'false') return false;
} catch (error) {
// continue regardless of error
}
return true;
};

Expand Down Expand Up @@ -366,7 +370,13 @@ export default function DataSourcePanel({
<StyledInfoboxWrapper>
<Alert
closable
onClose={() => sessionStorage.setItem('showInfobox', 'false')}
onClose={() => {
try {
sessionStorage.setItem('showInfobox', 'false');
} catch (error) {
// continue regardless of error
}
}}
type="info"
message=""
description={
Expand Down
19 changes: 14 additions & 5 deletions superset-frontend/src/explore/components/SaveModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,12 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
async componentDidMount() {
let { dashboardId } = this.props;
if (!dashboardId) {
const lastDashboard = sessionStorage.getItem(SK_DASHBOARD_ID);
let lastDashboard = null;
try {
lastDashboard = sessionStorage.getItem(SK_DASHBOARD_ID);
} catch (error) {
// continue regardless of error
}
dashboardId = lastDashboard && parseInt(lastDashboard, 10);
}
if (dashboardId) {
Expand Down Expand Up @@ -249,10 +254,14 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
);
}

if (dashboard) {
sessionStorage.setItem(SK_DASHBOARD_ID, `${dashboard.id}`);
} else {
sessionStorage.removeItem(SK_DASHBOARD_ID);
try {
if (dashboard) {
sessionStorage.setItem(SK_DASHBOARD_ID, `${dashboard.id}`);
} else {
sessionStorage.removeItem(SK_DASHBOARD_ID);
}
} catch (error) {
// continue regardless of error
}

// Go to new dashboard url
Expand Down
23 changes: 18 additions & 5 deletions superset-frontend/src/hooks/useTabId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,29 @@ export function useTabId() {
}

const updateTabId = () => {
const lastTabId = window.localStorage.getItem('last_tab_id');
let lastTabId;
try {
lastTabId = window.localStorage.getItem('last_tab_id');
} catch (error) {
// continue regardless of error
}
const newTabId = String(
lastTabId ? Number.parseInt(lastTabId, 10) + 1 : 1,
);
window.sessionStorage.setItem('tab_id', newTabId);
window.localStorage.setItem('last_tab_id', newTabId);
try {
window.sessionStorage.setItem('tab_id', newTabId);
window.localStorage.setItem('last_tab_id', newTabId);
} catch (error) {
// continue regardless of error
}
setTabId(newTabId);
};

const storedTabId = window.sessionStorage.getItem('tab_id');
let storedTabId;
try {
storedTabId = window.sessionStorage.getItem('tab_id');
} catch (error) {
// continue regardless of error
}
if (storedTabId) {
channel.postMessage({
type: 'REQUESTING_TAB_ID',
Expand Down
Loading