Skip to content

Commit

Permalink
Unify handling of backend and front end errors
Browse files Browse the repository at this point in the history
Exceptions from front end are special in the sense that they contain
stack trace.
  • Loading branch information
KKoukiou committed Feb 19, 2024
1 parent 5cbec64 commit 157dbec
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 11 deletions.
5 changes: 5 additions & 0 deletions src/actions/miscellaneous-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
});
26 changes: 17 additions & 9 deletions src/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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(() => {
Expand All @@ -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),
Expand Down Expand Up @@ -149,12 +158,12 @@ export const Application = () => {
<Page
data-debug={conf.Anaconda.debug}
>
{(criticalError || jsError) &&
{(criticalError || criticalErrorFrontend) &&
<CriticalError
exception={{ backendException: criticalError, frontendException: jsError }}
exception={{ backendException: criticalError, frontendException: criticalErrorFrontend }}
isConnected={state.network.connected}
reportLinkURL={bzReportURL} />}
{!jsError &&
{!criticalErrorFrontend &&
<>
{!showStorage &&
<PageGroup stickyOnBreakpoint={{ default: "top" }}>
Expand All @@ -170,7 +179,6 @@ export const Application = () => {
<WithDialogs>
<AnacondaWizard
onCritFail={onCritFail}
onJsError={setJsError}
title={title}
storageData={state.storage}
localizationData={state.localization}
Expand Down
4 changes: 3 additions & 1 deletion src/components/storage/CockpitStorageIntegration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ export const CockpitStorageIntegration = ({

useEffect(() => {
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]);
Expand Down
5 changes: 4 additions & 1 deletion src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 157dbec

Please sign in to comment.