From 6ec8709aa42fff3d545961bfed477849b37566bb Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 14 Jan 2025 11:47:14 -0500 Subject: [PATCH 1/3] CASH-61: add logging to GoToFunnelStartOn404 --- src/mixins/analytics-mixin.js | 13 +++++++ src/router/index.js | 68 +++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index e970e94a8..30f8328f0 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -650,6 +650,19 @@ export default { }); }, + pushPageErrorToDataLayer(error) { + + pushToDataLayerIfDefined({ + event: "page-error", + error: { + type: error.type || "", + cause: error.cause || "", + currentPage: error.currentPage || "", + nextPage: error.nextPage || "", + }, + }); + }, + prependActionToMethod(object, method, actionToPrepend) { const baseMethodName = method.name.startsWith("bound ") ? method.name.substring(6) diff --git a/src/router/index.js b/src/router/index.js index da3c1914c..028a6d85f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -65,9 +65,17 @@ const routes = [ // If the saved session has timed out, clear the session, execute 404 logic. if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { log(" --save session timeout go to start"); + + const errorPayload = { + cause: "expired session", + currentPage: from.query.fmgPage, + nextPage: to.query.fmgPage, + }; + await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); deleteFunnelCookie(); - GoToFunnelStartOn404(next); + GoToFunnelStartOn404(next, errorPayload); + return; } // Intercept all navigation if a submitted order exists in storage @@ -206,7 +214,14 @@ const routes = [ return; } - GoToFunnelStartOn404(next); + const errorPayload = { + cause: "invalid page prerequisites for page", + currentPage: from.query.fmgPage, + nextPage: to.query.fmgPage, + }; + + GoToFunnelStartOn404(next, errorPayload); + return; } log(" --has route:", to.query.fmgPage); @@ -214,9 +229,15 @@ const routes = [ } if (!isExistingFmgPageName(to.query.fmgPage)) { - console.log("Not an existing fmg page name:" + to.query.fmgPage); - GoToFunnelStartOn404(next); + const errorPayload = { + cause: "invalid page name", + currentPage: from.query.fmgPage, + nextPage: to.query.fmgPage, + }; + + GoToFunnelStartOn404(next, errorPayload); return; + } // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. @@ -237,9 +258,18 @@ const routes = [ .components.default(); if (!arePagePrerequisitesValid(nextComponent)) { + // prettier-ignore console.log("Page Prereqs not valid for next component: " + nextComponent.default.name); - GoToFunnelStartOn404(next); + + const errorPayload = { + cause: "invalid page prerequisites for page", + currentPage: from.query.fmgPage, + nextPage: to.query.fmgPage, + }; + + GoToFunnelStartOn404(next, errorPayload); + return; } log("------------- router index.js beforeEnter end -----------------"); @@ -261,7 +291,16 @@ const routes = [ console.log(new Date() + " Exception in beforeEnter:" + JSON.stringify(error)); // If we don't have a route, go to our 404 page. - GoToFunnelStartOn404(next); + const errorPayload = { + cause: "uncaught error in beforeEnter", + currentPage: from.query.fmgPage, + nextPage: to.query.fmgPage, + fullError: error, + errorStack: error.stack, + }; + + GoToFunnelStartOn404(next, errorPayload); + return; } }, }, @@ -399,6 +438,7 @@ router.navigateToExternalUrl = (url, optionalQuery = {}) => { router.navigateError = () => { DisplayPageError(); + /// TODO - Add error logging for dataLayer here? }; //Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example. @@ -588,7 +628,19 @@ function GetRouteInfoFromPageName(pageName) { } // Go to our start page on a 404. -function GoToFunnelStartOn404(next) { +function GoToFunnelStartOn404(next, errorPayload = null) { + if (errorPayload !== null) { + errorPayload.type = "GoToFunnelStartOn404"; + analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); + + console.log( + "%cGoToFunnelStartOn404()... errorPayload", + "color: white; background-color: blue; padding: 5px;", + errorPayload + ); + + } + // Put item on the bus eventBus.addEventToBus( globalEvents.Categories.GLOBAL_ALERT, @@ -608,6 +660,8 @@ function GoToFunnelStartOn404(next) { } async function DisplayPageError() { + console.log("%c running DisplayPageError()... ", "font-size: 20px; color: purple;"); + // Put item on the bus eventBus.addEventToBus( globalEvents.Categories.GLOBAL_ALERT, From fc834f9d1211658c6389f995a86442e3edad3083 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 15 Jan 2025 10:31:06 -0500 Subject: [PATCH 2/3] Additional error logging --- src/global-methods.js | 8 +++++++- src/mixins/analytics-mixin.js | 7 +------ src/router/index.js | 20 ++++++++++++++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/global-methods.js b/src/global-methods.js index 22512fe41..96c5e21fc 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -110,7 +110,13 @@ export default { if (error.response.status && error.response.status != "404") { // Do not route to error logic when no wipers found or no promo found (404s) - router.navigateError(); + const errorPayload = { + cause: `Response error ${error.response.status}`, + currentPage: pageNameToLog, + endpoint: endpoint, + }; + + router.navigateError(errorPayload); // do not log 404 errors from services because we return NotFound // when a service doesn't return an object diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 30f8328f0..d534a7200 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -654,12 +654,7 @@ export default { pushToDataLayerIfDefined({ event: "page-error", - error: { - type: error.type || "", - cause: error.cause || "", - currentPage: error.currentPage || "", - nextPage: error.nextPage || "", - }, + error: error, }); }, diff --git a/src/router/index.js b/src/router/index.js index 028a6d85f..d92f213bc 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -436,9 +436,8 @@ router.navigateToExternalUrl = (url, optionalQuery = {}) => { navigateToUrl(url, optionalQuery); }; -router.navigateError = () => { - DisplayPageError(); - /// TODO - Add error logging for dataLayer here? +router.navigateError = (errorPayload = null) => { + DisplayPageError(errorPayload); }; //Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example. @@ -659,9 +658,22 @@ function GoToFunnelStartOn404(next, errorPayload = null) { }); } -async function DisplayPageError() { +async function DisplayPageError(errorPayload = null) { console.log("%c running DisplayPageError()... ", "font-size: 20px; color: purple;"); + if(errorPayload !== null) { + errorPayload.type = "DisplayPageError"; + analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); + } else { + errorPayload = { + type: "DisplayPageError", + cause: "Unknown page error", + currentPage: getQuerystringParameter(queryStrings.FMG_PAGE), + nextPage: null, + }; + analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); + } + // Put item on the bus eventBus.addEventToBus( globalEvents.Categories.GLOBAL_ALERT, From 7af0c3f0a1da276f10ae5f44f189c65df8e27e66 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 15 Jan 2025 10:50:14 -0500 Subject: [PATCH 3/3] Defensive coding in error handling --- src/router/index.js | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index d92f213bc..0da560c84 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -68,8 +68,8 @@ const routes = [ const errorPayload = { cause: "expired session", - currentPage: from.query.fmgPage, - nextPage: to.query.fmgPage, + currentPage: from?.query?.fmgPage, + nextPage: to?.query?.fmgPage, }; await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); @@ -216,8 +216,8 @@ const routes = [ const errorPayload = { cause: "invalid page prerequisites for page", - currentPage: from.query.fmgPage, - nextPage: to.query.fmgPage, + currentPage: from?.query?.fmgPage, + nextPage: to?.query?.fmgPage, }; GoToFunnelStartOn404(next, errorPayload); @@ -231,8 +231,8 @@ const routes = [ if (!isExistingFmgPageName(to.query.fmgPage)) { const errorPayload = { cause: "invalid page name", - currentPage: from.query.fmgPage, - nextPage: to.query.fmgPage, + currentPage: from?.query?.fmgPage, + nextPage: to?.query?.fmgPage, }; GoToFunnelStartOn404(next, errorPayload); @@ -264,8 +264,8 @@ const routes = [ const errorPayload = { cause: "invalid page prerequisites for page", - currentPage: from.query.fmgPage, - nextPage: to.query.fmgPage, + currentPage: from?.query?.fmgPage, + nextPage: to?.query?.fmgPage, }; GoToFunnelStartOn404(next, errorPayload); @@ -293,10 +293,10 @@ const routes = [ // If we don't have a route, go to our 404 page. const errorPayload = { cause: "uncaught error in beforeEnter", - currentPage: from.query.fmgPage, - nextPage: to.query.fmgPage, + currentPage: from?.query?.fmgPage, + nextPage: to?.query?.fmgPage, fullError: error, - errorStack: error.stack, + errorStack: error?.stack, }; GoToFunnelStartOn404(next, errorPayload); @@ -665,11 +665,17 @@ async function DisplayPageError(errorPayload = null) { errorPayload.type = "DisplayPageError"; analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); } else { + // very cautiously to avoid additional errors: + var currentPage = ""; + try { + currentPage = getQuerystringParameter(queryStrings.FMG_PAGE); + } catch (e) { + // pass + } errorPayload = { type: "DisplayPageError", cause: "Unknown page error", - currentPage: getQuerystringParameter(queryStrings.FMG_PAGE), - nextPage: null, + currentPage: currentPage, }; analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); }