Stub error page
This commit is contained in:
parent
3d64175744
commit
e22f66eb83
9 changed files with 172 additions and 16 deletions
128
public/static/error/index.html
Normal file
128
public/static/error/index.html
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
EXCEPTION PAGE
|
||||||
|
</h1>
|
||||||
|
<hr />
|
||||||
|
<h2>
|
||||||
|
BAILOUT INFO:
|
||||||
|
</h2>
|
||||||
|
<div id="bailout-info-container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// Helpers
|
||||||
|
function getCookieValueByName(name) {
|
||||||
|
const value = "; " + document.cookie;
|
||||||
|
const parts = value.split("; " + name + "=");
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
return parts.pop().split(";").shift();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = () => {
|
||||||
|
// =============== Check for session info:
|
||||||
|
const existingVuexDataJSON = window.localStorage.getItem('vuex');
|
||||||
|
const existingVuexData = existingVuexDataJSON ? JSON.parse(existingVuexDataJSON) : null;
|
||||||
|
|
||||||
|
console.log(`================ VUEX DATA`);
|
||||||
|
console.log(existingVuexData);
|
||||||
|
|
||||||
|
// If no info exists, exit.
|
||||||
|
if(!existingVuexData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// =============== Collect diagnostic data:
|
||||||
|
const bailoutInfo = [];
|
||||||
|
|
||||||
|
// App & Site Name
|
||||||
|
bailoutInfo.push({ name: 'App Name', value: 'FixMyGlass' });
|
||||||
|
bailoutInfo.push({ name: 'Site Name', value: 'SafeliteDotcom' });
|
||||||
|
|
||||||
|
// Not included (yet) from heritage:
|
||||||
|
// - Site ID
|
||||||
|
// - Code
|
||||||
|
// - Module
|
||||||
|
// - Page
|
||||||
|
|
||||||
|
bailoutInfo.push({ name: 'Timestamp', value: `${new Date()}` });
|
||||||
|
|
||||||
|
// - URL
|
||||||
|
// - Server
|
||||||
|
|
||||||
|
const sessionId = getCookieValueByName('sid');
|
||||||
|
bailoutInfo.push({ name: 'Session Id', value: sessionId });
|
||||||
|
|
||||||
|
const userAgent = window.navigator.userAgent;
|
||||||
|
bailoutInfo.push({ name: 'User Agent', value: userAgent });
|
||||||
|
|
||||||
|
// - IP
|
||||||
|
// - Session Log Sequence Number
|
||||||
|
|
||||||
|
bailoutInfo.push({ name: 'Referral Seq Number', value: existingVuexData.order?.referralSequenceNumber });
|
||||||
|
bailoutInfo.push({ name: 'Referral Number', value: existingVuexData.order?.referralNumber });
|
||||||
|
bailoutInfo.push({ name: 'Referral Date', value: existingVuexData.order?.referralDate });
|
||||||
|
bailoutInfo.push({ name: 'Referral Provider Number', value: existingVuexData.order?.serviceLocation?.provider?.providerNumber });
|
||||||
|
bailoutInfo.push({ name: 'Referral CTU', value: existingVuexData.order?.serviceLocation?.provider?.address?.zipCodeCtu });
|
||||||
|
|
||||||
|
// - Referral Insured Zip
|
||||||
|
// - Referral Insured Service Zip
|
||||||
|
|
||||||
|
bailoutInfo.push({ name: 'Referral CarID', value: existingVuexData.order?.vehicle?.carId });
|
||||||
|
|
||||||
|
const vehicle = existingVuexData.order?.vehicle;
|
||||||
|
const vehicleString = vehicle?.year
|
||||||
|
? `${vehicle.year} ${vehicle.make} ${vehicle.model} - ${vehicle.style}`
|
||||||
|
: null;
|
||||||
|
bailoutInfo.push({ name: 'Referral Vehicle', value: vehicleString });
|
||||||
|
bailoutInfo.push({ name: 'Work Order Number', value: existingVuexData.order?.workOrderNumber });
|
||||||
|
bailoutInfo.push({ name: 'Work Order ID', value: existingVuexData.order?.workOrderId });
|
||||||
|
bailoutInfo.push({ name: 'Parent Account Number', value: existingVuexData.order?.payment?.parentAccountNumber });
|
||||||
|
|
||||||
|
// - Parent Account Name
|
||||||
|
// - Client GUID
|
||||||
|
|
||||||
|
// =============== Display diagnostic data:
|
||||||
|
// Create display nodes
|
||||||
|
const elements = bailoutInfo.map(
|
||||||
|
dataPoint => {
|
||||||
|
const element = document.createElement('li');
|
||||||
|
element.textContent = `${dataPoint.name}: ${dataPoint.value}`;
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const fragment = new DocumentFragment();
|
||||||
|
|
||||||
|
elements.forEach(
|
||||||
|
(element) => {
|
||||||
|
fragment.append(element);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Attach nodes to DOM and render
|
||||||
|
const attachNode = document.getElementById('bailout-info-container');
|
||||||
|
if(attachNode) {
|
||||||
|
const ul = attachNode.appendChild(document.createElement('ul'));
|
||||||
|
ul.append(fragment);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============== Clear User Data
|
||||||
|
// ======== To avoid reproducing the same issue due to invalid states.
|
||||||
|
window.localStorage.removeItem('vuex');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -121,7 +121,7 @@ export default {
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
router.bailout(errorPayload);
|
router.handleSoftError(errorPayload);
|
||||||
|
|
||||||
// do not log 404 errors from services because we return NotFound
|
// do not log 404 errors from services because we return NotFound
|
||||||
// when a service doesn't return an object
|
// when a service doesn't return an object
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ export const routeData = {
|
||||||
path: "/virtual/auto-route",
|
path: "/virtual/auto-route",
|
||||||
virtual: true,
|
virtual: true,
|
||||||
},
|
},
|
||||||
// TODO: RENAME FROM BAILOUT
|
|
||||||
ERROR: {
|
ERROR: {
|
||||||
name: "error",
|
name: "error",
|
||||||
path: "/virtual/error",
|
path: "/virtual/error",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { routes } from "@/router/methods/routes";
|
import { routes } from "@/router/methods/routes";
|
||||||
import { afterEach } from "@/router/methods/after-each";
|
import { afterEach } from "@/router/methods/after-each";
|
||||||
import { beforeEach } from "@/router/methods/before-each";
|
import { beforeEach } from "@/router/methods/before-each";
|
||||||
import { bailout } from "@/router/methods/error";
|
import { handleSoftError, handleHardError } from "@/router/methods/error";
|
||||||
import {
|
import {
|
||||||
navigateWithoutSaving,
|
navigateWithoutSaving,
|
||||||
navigateWithSaving,
|
navigateWithSaving,
|
||||||
|
|
@ -32,7 +32,8 @@ router.navigateWithoutSaving = navigateWithoutSaving;
|
||||||
router.navigateWithPageData = navigateWithPageData;
|
router.navigateWithPageData = navigateWithPageData;
|
||||||
router.navigateAndForceTopLevelNavigation = navigateAndForceTopLevelNavigation;
|
router.navigateAndForceTopLevelNavigation = navigateAndForceTopLevelNavigation;
|
||||||
|
|
||||||
router.bailout = bailout;
|
router.handleSoftError = handleSoftError;
|
||||||
|
router.handleHardError = handleHardError;
|
||||||
|
|
||||||
router.navigateToExternalUrl = navigateToExternalUrl;
|
router.navigateToExternalUrl = navigateToExternalUrl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
import { routeData, FUNNEL_START_PAGE } from "@/router/constants/routes";
|
import { routeData, FUNNEL_START_PAGE } from "@/router/constants/routes";
|
||||||
import { runExperiments } from "@/router/methods/helpers/run-experiments";
|
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 { checkPagePrerequisites } from "@/router/methods/page-prerequisites";
|
||||||
import { checkLogParam } from "@/helpers/debug-log-helper";
|
import { checkLogParam } from "@/helpers/debug-log-helper";
|
||||||
import { debugLog } 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,
|
nextPage: to?.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
bailout(errorPayload, true);
|
handleSoftError(errorPayload, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ export async function beforeEach(to, from) {
|
||||||
nextPage: to?.name,
|
nextPage: to?.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
bailout(errorPayload);
|
handleSoftError(errorPayload);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +107,8 @@ export async function beforeEach(to, from) {
|
||||||
|
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
||||||
bailout(errorPayload);
|
// Eject user from Vue app in this scenario and clear localstorage.
|
||||||
|
handleHardError(errorPayload);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import store from "@/store";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
|
||||||
export async function bailout(errorPayload, forceRestart = false) {
|
export async function handleSoftError(errorPayload, forceRestart = false) {
|
||||||
if (forceRestart) {
|
if (forceRestart) {
|
||||||
await store.dispatch(storeActions.RESET_STATE);
|
await store.dispatch(storeActions.RESET_STATE);
|
||||||
deleteFunnelCookie();
|
deleteFunnelCookie();
|
||||||
|
|
@ -17,3 +17,11 @@ export async function bailout(errorPayload, forceRestart = false) {
|
||||||
name: routeData.ERROR.name,
|
name: routeData.ERROR.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function handleHardError(errorPayload) {
|
||||||
|
try {
|
||||||
|
analyticsMixin?.methods?.pushPageErrorToDataLayer(errorPayload);
|
||||||
|
} finally {
|
||||||
|
window.top.location = "/fmg/static/error/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export function createRoute(routeDatum, beforeEnter = async (to, from) => undefi
|
||||||
return await beforeEnter(to, from);
|
return await beforeEnter(to, from);
|
||||||
} catch {
|
} catch {
|
||||||
return {
|
return {
|
||||||
name: routeData.BAILOUT.name,
|
name: routeData.ERROR.name,
|
||||||
replace: true,
|
replace: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ export function createVirtualRoute(routeDatum, beforeEnter = async (to, from) =>
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return {
|
return {
|
||||||
name: routeData.BAILOUT.name,
|
name: routeData.ERROR.name,
|
||||||
replace: true,
|
replace: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { savePageData } from "@/router/methods/helpers/save-page-data";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import store from "@/store";
|
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) {
|
async function navigate(scenario, currentPageName, withSaving = false, forceTopLevelNav = false) {
|
||||||
// Check to see if calling page is same as current page.
|
// 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,
|
nextPage: nextPage?.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
bailout(errorPayload);
|
handleSoftError(errorPayload);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,34 @@ import baseMixin from "@/mixins/base-mixin";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { routeData, FUNNEL_START_PAGE } from "@/router/constants/routes";
|
import { routeData, FUNNEL_START_PAGE } from "@/router/constants/routes";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
import { handleHardError } from "@/router/methods/error";
|
||||||
|
|
||||||
export async function errorBeforeEnter(to, from) {
|
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.
|
// If we've already encountered one error, clear session to avoid more.
|
||||||
// Otherwise mark that we encoutnered an error here.
|
// Otherwise mark that we encoutnered an error here.
|
||||||
if (store.getters.applicationUser.hasAlreadyTriggeredError) {
|
if (store.getters.applicationUser.hasAlreadyTriggeredError) {
|
||||||
return {
|
const errorPayload = {
|
||||||
name: routeData.RESTART.name,
|
cause: "Successive errors triggered.",
|
||||||
replace: true,
|
currentPage: from?.name,
|
||||||
|
nextPage: to?.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleHardError(errorPayload);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
await store.dispatch(storeActions.UPDATE_HAS_TRIGGERED_ERROR, true);
|
await store.dispatch(storeActions.UPDATE_HAS_TRIGGERED_ERROR, true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue