You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2023/10/13 12:15:13 UTC

[superset] 04/06: fix(window): unavailable localStorage and sessionStorage (#25599)

This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit a0b2dc4266ea834ab397d463580cc3856d01fe4d
Author: Fabien <18...@users.noreply.github.com>
AuthorDate: Wed Oct 11 19:31:30 2023 +0200

    fix(window): unavailable localStorage and sessionStorage (#25599)
---
 .../src/SqlLab/reducers/getInitialState.js         | 102 +++++++++++----------
 superset-frontend/src/SqlLab/reducers/sqlLab.js    |  49 ++++++----
 .../explore/components/DatasourcePanel/index.tsx   |  14 ++-
 .../src/explore/components/SaveModal.tsx           |  19 +++-
 superset-frontend/src/hooks/useTabId.ts            |  23 ++++-
 5 files changed, 127 insertions(+), 80 deletions(-)

diff --git a/superset-frontend/src/SqlLab/reducers/getInitialState.js b/superset-frontend/src/SqlLab/reducers/getInitialState.js
index dd24054e11..00b0128148 100644
--- a/superset-frontend/src/SqlLab/reducers/getInitialState.js
+++ b/superset-frontend/src/SqlLab/reducers/getInitialState.js
@@ -137,57 +137,61 @@ export default function getInitialState({
 
   const queries = { ...queries_ };
 
-  /**
-   * If the `SQLLAB_BACKEND_PERSISTENCE` feature flag is off, or if the user
-   * hasn't used SQL Lab after it has been turned on, the state will be stored
-   * in the browser's local storage.
-   */
-  if (
-    localStorage.getItem('redux') &&
-    JSON.parse(localStorage.getItem('redux')).sqlLab
-  ) {
-    const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
+  try {
+    /**
+     * If the `SQLLAB_BACKEND_PERSISTENCE` feature flag is off, or if the user
+     * hasn't used SQL Lab after it has been turned on, the state will be stored
+     * in the browser's local storage.
+     */
+    if (
+      localStorage.getItem('redux') &&
+      JSON.parse(localStorage.getItem('redux')).sqlLab
+    ) {
+      const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
 
-    if (sqlLab.queryEditors.length === 0) {
-      // migration was successful
-      localStorage.removeItem('redux');
-    } else {
-      unsavedQueryEditor = sqlLab.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 || {};
+        // 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 {
diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.js b/superset-frontend/src/SqlLab/reducers/sqlLab.js
index 66850ce079..e6e0a54ed9 100644
--- a/superset-frontend/src/SqlLab/reducers/sqlLab.js
+++ b/superset-frontend/src/SqlLab/reducers/sqlLab.js
@@ -424,13 +424,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),
@@ -439,12 +442,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(
@@ -454,12 +461,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,
       );
diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
index 1d85c8235f..80ed37a301 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
@@ -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;
   };
 
@@ -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={
diff --git a/superset-frontend/src/explore/components/SaveModal.tsx b/superset-frontend/src/explore/components/SaveModal.tsx
index 86ff27bb42..d390e46388 100644
--- a/superset-frontend/src/explore/components/SaveModal.tsx
+++ b/superset-frontend/src/explore/components/SaveModal.tsx
@@ -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) {
@@ -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
diff --git a/superset-frontend/src/hooks/useTabId.ts b/superset-frontend/src/hooks/useTabId.ts
index 4f60763c88..56857cca64 100644
--- a/superset-frontend/src/hooks/useTabId.ts
+++ b/superset-frontend/src/hooks/useTabId.ts
@@ -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',