diff --git a/public/static/error/index.html b/public/static/error/index.html new file mode 100644 index 000000000..539a7fb88 --- /dev/null +++ b/public/static/error/index.html @@ -0,0 +1,128 @@ + + + + + + +

+ EXCEPTION PAGE +

+
+

+ BAILOUT INFO: +

+
+ +
+ + + \ No newline at end of file diff --git a/src/global-methods.js b/src/global-methods.js index 0bd0549ea..fc0b3cb41 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -121,7 +121,7 @@ export default { endpoint: endpoint, }; - router.bailout(errorPayload); + router.handleSoftError(errorPayload); // do not log 404 errors from services because we return NotFound // when a service doesn't return an object diff --git a/src/router/constants/routes.js b/src/router/constants/routes.js index 5632fe357..98d6c503a 100644 --- a/src/router/constants/routes.js +++ b/src/router/constants/routes.js @@ -112,7 +112,6 @@ export const routeData = { path: "/virtual/auto-route", virtual: true, }, - // TODO: RENAME FROM BAILOUT ERROR: { name: "error", path: "/virtual/error", diff --git a/src/router/index.js b/src/router/index.js index cd842c5cb..aa07a7a0b 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,7 +1,7 @@ import { routes } from "@/router/methods/routes"; import { afterEach } from "@/router/methods/after-each"; import { beforeEach } from "@/router/methods/before-each"; -import { bailout } from "@/router/methods/error"; +import { handleSoftError, handleHardError } from "@/router/methods/error"; import { navigateWithoutSaving, navigateWithSaving, @@ -32,7 +32,8 @@ router.navigateWithoutSaving = navigateWithoutSaving; router.navigateWithPageData = navigateWithPageData; router.navigateAndForceTopLevelNavigation = navigateAndForceTopLevelNavigation; -router.bailout = bailout; +router.handleSoftError = handleSoftError; +router.handleHardError = handleHardError; router.navigateToExternalUrl = navigateToExternalUrl; diff --git a/src/router/methods/before-each.js b/src/router/methods/before-each.js index e742f89ff..1796b40d7 100644 --- a/src/router/methods/before-each.js +++ b/src/router/methods/before-each.js @@ -8,7 +8,7 @@ import analyticsMixin from "@/mixins/analytics-mixin"; import { routeData, FUNNEL_START_PAGE } from "@/router/constants/routes"; import { runExperiments } from "@/router/methods/helpers/run-experiments"; -import { bailout } from "@/router/methods/error"; +import { handleSoftError, handleHardError } from "@/router/methods/error"; import { checkPagePrerequisites } from "@/router/methods/page-prerequisites"; import { checkLogParam } from "@/helpers/debug-log-helper"; import { debugLog } from "@/helpers/debug-log-helper"; @@ -41,7 +41,7 @@ export async function beforeEach(to, from) { nextPage: to?.name, }; - bailout(errorPayload, true); + handleSoftError(errorPayload, true); return false; } @@ -88,7 +88,7 @@ export async function beforeEach(to, from) { nextPage: to?.name, }; - bailout(errorPayload); + handleSoftError(errorPayload); return; } @@ -107,7 +107,8 @@ export async function beforeEach(to, from) { console.log(error); - bailout(errorPayload); + // Eject user from Vue app in this scenario and clear localstorage. + handleHardError(errorPayload); return; } } diff --git a/src/router/methods/error.js b/src/router/methods/error.js index 06eea69b0..c9f4e30a5 100644 --- a/src/router/methods/error.js +++ b/src/router/methods/error.js @@ -5,7 +5,7 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions"; import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; -export async function bailout(errorPayload, forceRestart = false) { +export async function handleSoftError(errorPayload, forceRestart = false) { if (forceRestart) { await store.dispatch(storeActions.RESET_STATE); deleteFunnelCookie(); @@ -17,3 +17,11 @@ export async function bailout(errorPayload, forceRestart = false) { name: routeData.ERROR.name, }); } + +export async function handleHardError(errorPayload) { + try { + analyticsMixin?.methods?.pushPageErrorToDataLayer(errorPayload); + } finally { + window.top.location = "/fmg/static/error/"; + } +} diff --git a/src/router/methods/helpers/create-route.js b/src/router/methods/helpers/create-route.js index 32410e3b3..828777603 100644 --- a/src/router/methods/helpers/create-route.js +++ b/src/router/methods/helpers/create-route.js @@ -11,7 +11,7 @@ export function createRoute(routeDatum, beforeEnter = async (to, from) => undefi return await beforeEnter(to, from); } catch { return { - name: routeData.BAILOUT.name, + name: routeData.ERROR.name, replace: true, }; } @@ -29,7 +29,7 @@ export function createVirtualRoute(routeDatum, beforeEnter = async (to, from) => } catch (error) { console.log(error); return { - name: routeData.BAILOUT.name, + name: routeData.ERROR.name, replace: true, }; } diff --git a/src/router/methods/navigate.js b/src/router/methods/navigate.js index b15c955e9..25c58e7e5 100644 --- a/src/router/methods/navigate.js +++ b/src/router/methods/navigate.js @@ -5,7 +5,7 @@ import { savePageData } from "@/router/methods/helpers/save-page-data"; import router from "@/router"; import store from "@/store"; -import { bailout } from "@/router/methods/error"; +import { handleSoftError } from "@/router/methods/error"; async function navigate(scenario, currentPageName, withSaving = false, forceTopLevelNav = false) { // Check to see if calling page is same as current page. @@ -30,7 +30,7 @@ async function navigate(scenario, currentPageName, withSaving = false, forceTopL nextPage: nextPage?.name, }; - bailout(errorPayload); + handleSoftError(errorPayload); return; } diff --git a/src/router/methods/route-logic/error.js b/src/router/methods/route-logic/error.js index 8707a65d9..9f86f7acf 100644 --- a/src/router/methods/route-logic/error.js +++ b/src/router/methods/route-logic/error.js @@ -5,15 +5,34 @@ import baseMixin from "@/mixins/base-mixin"; import router from "@/router"; import { routeData, FUNNEL_START_PAGE } from "@/router/constants/routes"; import store from "@/store"; +import { handleHardError } from "@/router/methods/error"; export async function errorBeforeEnter(to, from) { + // Check if `hasAlreadyTriggeredErrror` is available. + // If we cannot check it (store, getters, or applicationUser is null-ish), + // act as if the flag is set, as we are in unstable state. + if (!store?.getters?.applicationUser) { + const errorPayload = { + cause: "Cannot access store during error process.", + currentPage: from?.name, + nextPage: to?.name, + }; + + handleHardError(errorPayload); + return; + } + // If we've already encountered one error, clear session to avoid more. // Otherwise mark that we encoutnered an error here. if (store.getters.applicationUser.hasAlreadyTriggeredError) { - return { - name: routeData.RESTART.name, - replace: true, + const errorPayload = { + cause: "Successive errors triggered.", + currentPage: from?.name, + nextPage: to?.name, }; + + handleHardError(errorPayload); + return; } else { await store.dispatch(storeActions.UPDATE_HAS_TRIGGERED_ERROR, true); }