diff --git a/src/global-methods.js b/src/global-methods.js index 7a6fcf33..7f7ad72b 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -94,10 +94,11 @@ export default { } if (error.response.status !== 404) { - global.$logger.logError(`${method}: ${endpoint}: ${error.message}`, error.response); + const errorData = { method, url, payload, error }; + global.$logger.logError(`${method}: ${endpoint}`, errorData); if (bailoutOnError && global.bailoutOnAxiosError !== undefined) { - global.bailoutOnAxiosError({ method, url, payload, error }); + global.bailoutOnAxiosError(errorData); } } return reject(error.response); diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index c3b6c8ee..9cedd58d 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -214,7 +214,6 @@ export default { }); this.navigateForward(); } catch (e) { - debugger; if (e.isAxiosError && e.status === 404) { this.mainStore.resetVehicleState(); useMainStore().updateVehicle({ diff --git a/src/layouts/vehicle-selection/vehicle-selection.vue b/src/layouts/vehicle-selection/vehicle-selection.vue index 1cfb7f4d..e489fe0d 100644 --- a/src/layouts/vehicle-selection/vehicle-selection.vue +++ b/src/layouts/vehicle-selection/vehicle-selection.vue @@ -163,16 +163,18 @@ export default { } }, selectedStyle(value) { - this.resetAlert(); - this.mainStore.updateVehicleStyle(value); - this.mainStore.setVehicle( - this.selectedYear, - this.selectedMake, - this.selectedModel, - this.selectedStyle - ).then((result) => { - this.displayNoServiceAlert = !result.data.canSafeliteService; - }); + if (value) { + this.resetAlert(); + this.mainStore.updateVehicleStyle(value); + this.mainStore.setVehicle( + this.selectedYear, + this.selectedMake, + this.selectedModel, + this.selectedStyle + ).then((result) => { + this.displayNoServiceAlert = !result.data.canSafeliteService; + }); + } } }, mounted() { diff --git a/src/main.js b/src/main.js index 243335b9..440bcaca 100644 --- a/src/main.js +++ b/src/main.js @@ -48,7 +48,7 @@ function getPageName(vm) { // Vue Error Handling vueApp.config.errorHandler = (err, vm, info) => { const pageName = getPageName(vm); - global.$logger.logError(`Page Name - ${pageName} - ${info}: ${err.message}\n${err.stack}`); + global.$logger.logError(`[${pageName}] ${info}`, err); if (applicationConfig.BAILOUT_ON_APPLICATION_ERROR) { router.navigateBailout(bailoutMessage.applicationError(`[${pageName}] ${info}: ${err.message}\n${err.stack}`)); } @@ -56,7 +56,7 @@ vueApp.config.errorHandler = (err, vm, info) => { // Vue Router Error Handling router.onError((err) => { - global.$logger.logError(err.message, err.cause); + global.$logger.logError('Router Error:', err); if (applicationConfig.BAILOUT_ON_ROUTER_ERROR) { router.navigateBailout(bailoutMessage.routerError(`${err.message}\n${err.stack}`)); } diff --git a/src/store/index.js b/src/store/index.js index 862206e8..c36f5ae2 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -25,6 +25,7 @@ import { buildURLSearchParams, getPartNumbersListForQueryString } from '@/helper import { getTopLevelGlassPartsWithRecal } from '@/helpers/recal-helper'; import { getDateForSavedSessionTimeout } from '@/helpers/session-helper'; import issPageValues from '@/router/router-constants/issPage-values'; +import CoverageStatuses from '@/constants/coverage-statuses'; const storeId = 'main'; @@ -528,12 +529,16 @@ export const useMainStore = defineStore({ payload: {} }); }, - getIsVinbyAddressPermissible() { - return globalMethods.callHttpClient({ - method: endpoints.IsVinbyAddressPermissible.method, - endpoint: `${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`, - payload: {} - }); + async getIsVinbyAddressPermissible() { + try { + return globalMethods.callHttpClient({ + method: endpoints.IsVinbyAddressPermissible.method, + endpoint: `${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`, + payload: {} + }); + } catch (e) { + return false; + } }, async getCoveragePolicyInfo() { const { order, issConfig, applicationUser } = this; @@ -547,42 +552,47 @@ export const useMainStore = defineStore({ this.applicationUser.coverageAttempts += 1; console.log(`Coverage lookup attempt #${this.applicationUser.coverageAttempts}. Max attempts allowed: 10.`); - const response = await globalMethods.callHttpClient({ - method: endpoints.CoveragePolicyInfo.method, - endpoint: endpoints.CoveragePolicyInfo.url, - payload: { - accountNumber: order.parentAccountNumber?.toString(), - policyNumber: policy.policyNumber, - dateOfLoss: policy.dateOfLoss, - zipCode: policy.policyZipCode, - referralCorrelationId: order.referralCorrelationId + try { + const response = await globalMethods.callHttpClient({ + method: endpoints.CoveragePolicyInfo.method, + endpoint: endpoints.CoveragePolicyInfo.url, + payload: { + accountNumber: order.parentAccountNumber?.toString(), + policyNumber: policy.policyNumber, + dateOfLoss: policy.dateOfLoss, + zipCode: policy.policyZipCode, + referralCorrelationId: order.referralCorrelationId + }, + bailoutOnError: false + }); + + const responsePolicy = response?.data?.policies?.[0]; + if (responsePolicy) { + this.updateCoverageType(coverageType.Deductible); + const insured = responsePolicy.insureds?.[0]; + + // populate parent account number + if (response.data.accountNumber) { + order.parentAccountNumber = parseInt(response.data.accountNumber, 10); + } + + // populate policy holder details from policy lookup + order.customer.address.streetAddress = insured?.address; + order.customer.address.city = insured?.city; + order.customer.address.state = insured?.state; + order.customer.address.zipCode = insured?.zipCode?.toString(); + order.customer.firstName = insured?.firstName; + order.customer.lastName = insured?.lastName; + + // populate additional fields + order.policy.policyData = responsePolicy.policyData; + + // populate vehicles + order.policy.vehicles = responsePolicy.vehicles ?? []; + } else { + this.updateCoverageType(coverageType.NONE); } - }); - - const responsePolicy = response?.data?.policies?.[0]; - if (responsePolicy) { - this.updateCoverageType(coverageType.Deductible); - const insured = responsePolicy.insureds?.[0]; - - // populate parent account number - if (response.data.accountNumber) { - order.parentAccountNumber = parseInt(response.data.accountNumber, 10); - } - - // populate policy holder details from policy lookup - order.customer.address.streetAddress = insured?.address; - order.customer.address.city = insured?.city; - order.customer.address.state = insured?.state; - order.customer.address.zipCode = insured?.zipCode?.toString(); - order.customer.firstName = insured?.firstName; - order.customer.lastName = insured?.lastName; - - // populate additional fields - order.policy.policyData = responsePolicy.policyData; - - // populate vehicles - order.policy.vehicles = responsePolicy.vehicles ?? []; - } else { + } catch (e) { this.updateCoverageType(coverageType.NONE); } }, @@ -601,82 +611,81 @@ export const useMainStore = defineStore({ updateIsItacOptimized(isItacOptimized) { this.order.insuranceCoverage.isItacOptimized = isItacOptimized || false; }, - registerClaim() { + async registerClaim() { const nonNumberCharRegex = /[^0-9]/g; - const { order, isITAC } = this; - return new Promise((resolve, reject) => { - globalMethods.callHttpClient({ + const { isITAC } = this; + + try { + const response = await globalMethods.callHttpClient({ method: endpoints.RegisterClaim.method, endpoint: endpoints.RegisterClaim.url, payload: - { - referralCorrelationId: this.order.referralCorrelationId, - accountNumber: this.order.parentAccountNumber?.toString() ?? '', - policyData: this.order.policy.policyData, - isItac: isITAC, - insured: { - firstName: this.order.customer.firstName, - lastName: this.order.customer.lastName, - address: { - addressLine1: this.order.customer.address.streetAddress, - addressLine2: this.order.customer.address.streetAddress2, - city: this.order.customer.address.city, - state: this.order.customer.address.state, - zipCode: this.order.customer.address.zipCode, - country: 'US' // TODO set from store + { + referralCorrelationId: this.order.referralCorrelationId, + accountNumber: this.order.parentAccountNumber?.toString() ?? '', + policyData: this.order.policy.policyData, + isItac: isITAC, + insured: { + firstName: this.order.customer.firstName, + lastName: this.order.customer.lastName, + address: { + addressLine1: this.order.customer.address.streetAddress, + addressLine2: this.order.customer.address.streetAddress2, + city: this.order.customer.address.city, + state: this.order.customer.address.state, + zipCode: this.order.customer.address.zipCode, + country: 'US' // TODO set from store + }, + homePhone: { + number: this.contactInfo.homePhone?.replaceAll(nonNumberCharRegex, '') ?? '' + } }, - homePhone: { - number: this.contactInfo.homePhone?.replaceAll(nonNumberCharRegex, '') ?? '' + driver: { + firstName: this.order.customer.firstName, + lastName: this.order.customer.lastName + }, + caller: { + homePhone: {} + }, + policyInfo: { + policyNumber: this.order.policy.policyNumber, + safelitePolicy: { + policies: [] + }, + actualDeductible: this.currentDeductible.toString() ?? '' + }, + lossInfo: { + dateOfLoss: this.order.policy.dateOfLoss, + location: { + city: this.order.policy.damageCity, + state: this.order.policy.damageState, + country: 'US' // TODO set from store + }, + vehicle: { + id: this.order.vehicle.policyVehicleId?.toString() ?? '', + year: this.order.vehicle.year?.toString() ?? '', + make: this.order.vehicle.make, + model: this.order.vehicle.model, + vin: this.order.vehicle.vin + }, + cause: this.order.policy.damageCause, + damageDescription: this.order.policy.damageCause } }, - driver: { - firstName: this.order.customer.firstName, - lastName: this.order.customer.lastName - }, - caller: { - homePhone: {} - }, - policyInfo: { - policyNumber: this.order.policy.policyNumber, - safelitePolicy: { - policies: [] - }, - actualDeductible: this.currentDeductible.toString() ?? '' - }, - lossInfo: { - dateOfLoss: this.order.policy.dateOfLoss, - location: { - city: this.order.policy.damageCity, - state: this.order.policy.damageState, - country: 'US' // TODO set from store - }, - vehicle: { - id: this.order.vehicle.policyVehicleId?.toString() ?? '', - year: this.order.vehicle.year?.toString() ?? '', - make: this.order.vehicle.make, - model: this.order.vehicle.model, - vin: this.order.vehicle.vin - }, - cause: this.order.policy.damageCause, - damageDescription: this.order.policy.damageCause - } - } - }).then((response) => { - this.order.insuranceCoverage.claimNumber = response.data.claimNumber; - if (response.data.isSuccess) { - this.updateCoverageStatus(coverageStatuses.VERIFIED); - } else { - this.updateCoverageStatus(coverageStatuses.NO_COVERAGE); - } - return resolve(response); - }, (error) => { - this.updateCoverageStatus(coverageStatuses.NO_COVERAGE); - this.order.insuranceCoverage.claimNumber = null; - return reject(error); + bailoutOnError: false }); - }); + this.order.insuranceCoverage.claimNumber = response.data.claimNumber; + if (response.data.isSuccess) { + this.updateCoverageStatus(coverageStatuses.VERIFIED); + } else { + this.updateCoverageStatus(coverageStatuses.NO_COVERAGE); + } + } catch (e) { + this.updateCoverageStatus(coverageStatuses.NO_COVERAGE); + this.order.insuranceCoverage.claimNumber = null; + } }, - getFinalDeductible() { + async getFinalDeductible() { const endorsementAnswersForPayload = []; const endorsementAnswers = this.order.policy.endorsementQuestionAnswers; if (endorsementAnswers) { @@ -692,9 +701,9 @@ export const useMainStore = defineStore({ glassInformation?.forEach((glassPiece) => { manualGlassNamesArray.push(glassPiece?.glassLocation?.toUpperCase()); }); - - return new Promise((resolve, reject) => { - globalMethods.callHttpClient({ + + try { + const r = await globalMethods.callHttpClient({ method: endpoints.FinalDeductible.method, endpoint: endpoints.FinalDeductible.url, payload: { @@ -716,16 +725,18 @@ export const useMainStore = defineStore({ vehicleVin: this.order.vehicle.vin, policyData: this.order.policy.policyData, isItac: this.isITAC - } - }).then((r) => { - this.order.policy.policyData = r.data.policyData; - this.updateDeductible(r.data); - return resolve(r); - }).catch((error) => reject(error)); - }); + }, + bailoutOnError: false + }); + this.order.policy.policyData = r.data.policyData; + this.updateDeductible(r.data); + return r; + } catch (e) { + this.updateCoverageStatus(CoverageStatuses.PENDING); + } }, - getDuplicateReferrals() { + async getDuplicateReferrals() { const params = new URLSearchParams({ parentAccountNumber: this.order.parentAccountNumber, customerPhoneNumber: this.order.contactInfo.servicePhone, @@ -734,18 +745,16 @@ export const useMainStore = defineStore({ dateOfLoss: this.order.policy.dateOfLoss }); - return new Promise((resolve, reject) => { - globalMethods.callHttpClient({ + try { + const duplicates = await globalMethods.callHttpClient({ method: endpoints.DuplicateSearch.method, - endpoint: `${endpoints.DuplicateSearch.url}?${params.toString()}` - }).then((r) => { - this.applicationUser.duplicateOrders = r.data ?? []; - return resolve(r.data); - }).catch((error) => { - this.applicationUser.duplicateOrders = []; - return reject(error); + endpoint: `${endpoints.DuplicateSearch.url}?${params.toString()}`, + bailoutOnError: false }); - }); + this.applicationUser.duplicateOrders = duplicates.data ?? []; + } catch (e) { + this.applicationUser.duplicateOrders = []; + } }, async lookupVinByPlate(licensePlate, licenseState) { try { diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 24c6139f..0e0900d2 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -459,9 +459,9 @@ describe('Store', () => { expect(store.order.insuranceCoverage.claimNumber).not.toBeNull(); }); - it('Call to client returns exception, resulting in object with error property being returned', async () => { + it('Call to client returns exception, and no error is returned from registerClaim method', async () => { // Arrange - expect.assertions(4); + expect.assertions(3); const error = 'register claim error'; globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.reject(error)); store.order.insuranceCoverage.coverageStatus = coverageStatuses.PENDING; @@ -1494,8 +1494,8 @@ describe('Store', () => { // Assert expect(globalMethods.callHttpClient).toHaveBeenCalled(); }); - it('api call throws exception => insuranceCoverage.coverageType is NONE', async () => { - expect.assertions(3); + it('api call throws exception => no error is thrown from getCoveragePolicyInfo and insuranceCoverage.coverageType is NONE', async () => { + expect.assertions(2); const error = 'get coverage policy info error'; store.issConfig.isCoverageEnabled = true; store.applicationUser.coverageLookupAttempts = 0; @@ -1567,9 +1567,9 @@ describe('Store', () => { expect(globalMethods.callHttpClient).toHaveBeenCalled(); expect(store.applicationUser.duplicateOrders).toEqual(expected); }); - it('Call to client returns exception => object with error property returned and duplicateReferrals set to []', async () => { + it('Call to client returns exception => object with error property returned and duplicateReferrals set to [] and no error is returned from getDuplicateReferrals', async () => { // Arrange - expect.assertions(3); + expect.assertions(2); const error = 'get duplicate referrals error'; globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.reject(error)); @@ -1807,7 +1807,8 @@ describe('Store', () => { vehicleVin, policyData, isItac: store.isITAC - }) + }), + bailoutOnError: false })); }); it('only "Yes" endorsement answers are added to payload', () => { @@ -1912,14 +1913,15 @@ describe('Store', () => { vehicleVin, policyData, isItac: store.isITAC - }) + }), + bailoutOnError: false })); }); }); describe('unsuccessful api call', () => { - it('api call throws exception', async () => { + it('api call throws exception. no error from getFinalDeductible', async () => { // Arrange - expect.assertions(2); + expect.assertions(1); const error = 'final deductible error'; globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.reject(error)); @@ -2078,8 +2080,8 @@ describe('Store', () => { expect(result.data.shopProviders[1]).toBe(provider2); }); }); - it('api call throws exception => coverageType none', async () => { - expect.assertions(3); + it('api call throws exception => coverageType none and no error from getCoveragePolicyInfo', async () => { + expect.assertions(2); const error = 'get coverage policy info error'; store.issConfig.isCoverageEnabled = true;