diff --git a/src/actions/miscellaneous-actions.js b/src/actions/miscellaneous-actions.js index c6f69a2661..34a98221f2 100644 --- a/src/actions/miscellaneous-actions.js +++ b/src/actions/miscellaneous-actions.js @@ -19,3 +19,8 @@ export const setCriticalErrorAction = (criticalError) => ({ type: "SET_CRITICAL_ERROR", payload: { criticalError } }); + +export const setCriticalErrorFrontendAction = (criticalErrorFrontend) => ({ + type: "SET_CRITICAL_ERROR_FRONTEND", + payload: { criticalErrorFrontend } +}); diff --git a/src/components/app.jsx b/src/components/app.jsx index 2423b92b99..8f93a00a25 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -40,7 +40,7 @@ import { NetworkClient, initDataNetwork, startEventMonitorNetwork } from "../api import { UsersClient } from "../apis/users"; import { EmptyStatePanel } from "cockpit-components-empty-state"; -import { setCriticalErrorAction } from "../actions/miscellaneous-actions.js"; +import { setCriticalErrorFrontendAction, setCriticalErrorAction } from "../actions/miscellaneous-actions.js"; import { readConf } from "../helpers/conf.js"; import { debug } from "../helpers/log.js"; @@ -58,11 +58,20 @@ export const Application = () => { const [state, dispatch] = useReducerWithThunk(reducer, initialState); const [storeInitilized, setStoreInitialized] = useState(false); const criticalError = state?.error?.criticalError; - const [jsError, setJsError] = useState(); + const criticalErrorFrontend = state?.error?.criticalErrorFrontend; const [showStorage, setShowStorage] = useState(false); const onCritFail = useCallback((contextData) => { - return errorHandlerWithContext(contextData, exc => dispatch(setCriticalErrorAction(exc))); + return errorHandlerWithContext( + contextData, + exc => { + if (contextData.isFrontend) { + dispatch(setCriticalErrorFrontendAction(exc)); + } else { + dispatch(setCriticalErrorAction(exc)); + } + } + ); }, [dispatch]); useEffect(() => { @@ -81,11 +90,11 @@ export const Application = () => { // Listen on JS errors window.onerror = (message, url, line, col, errObj) => { - setJsError(errObj); + dispatch(setCriticalErrorFrontendAction(errObj)); }; cockpit.file("/run/anaconda/bus.address").watch(address => { - setCriticalErrorAction(); + dispatch(setCriticalErrorAction()); const clients = [ new LocalizationClient(address), new StorageClient(address), @@ -149,12 +158,12 @@ export const Application = () => { - {(criticalError || jsError) && + {(criticalError || criticalErrorFrontend) && } - {!jsError && + {!criticalErrorFrontend && <> {!showStorage && @@ -170,7 +179,6 @@ export const Application = () => { { const iframe = document.getElementById("cockpit-storage-frame"); - iframe.contentWindow.addEventListener("error", err => onJsError({ ...err, jsContext: _("Storage plugin failed") })); + iframe.contentWindow.addEventListener("error", exception => { + onCritFail({ isFrontend: true, context: _("Storage plugin failed") })(exception.error); + }); resetPartitioning().then(() => setNeedsResetPartitioning(false), onCritFail); }, [onCritFail, onJsError]); diff --git a/src/reducer.js b/src/reducer.js index dd9cacbfbe..bd367556e3 100644 --- a/src/reducer.js +++ b/src/reducer.js @@ -43,7 +43,8 @@ export const networkInitialState = { /* Initial state for the error store substate */ export const errorInitialState = { - criticalError: null + criticalErrorBackend: null, + criticalErrorFrontend: null }; /* Intial state for the runtime store substate */ @@ -124,6 +125,8 @@ export const networkReducer = (state = networkInitialState, action) => { const errorReducer = (state = errorInitialState, action) => { if (action.type === "SET_CRITICAL_ERROR") { return { ...state, criticalError: action.payload.criticalError }; + } else if (action.type === "SET_CRITICAL_ERROR_FRONTEND") { + return { ...state, criticalErrorFrontend: action.payload.criticalErrorFrontend }; } else { return state; }