diff --git a/.vscode/settings.json b/.vscode/settings.json index 36fb84cf1c765d44fb033da790d9ed1df38772d0..6ad131c5e807ccc7c1b0381a5a2f6073e5f150df 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,6 +22,7 @@ "source.fixAll": true, "source.organizeImports": true }, + "editor.defaultFormatter": "esbenp.prettier-vscode", "cSpell.words": [ "acces", "apikey", diff --git a/__tests__/core/contractActivation.spec.js b/__tests__/core/contractActivation.spec.js index 39bf05c05941c9d78d2d0f103db3ae91549a063f..09e4fbfb03d398e81cfccd1940a8b72fa764c615 100644 --- a/__tests__/core/contractActivation.spec.js +++ b/__tests__/core/contractActivation.spec.js @@ -36,7 +36,7 @@ describe('activateContract', () => { ) expect(serviceId).toBe(78232791) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } mockParseServiceId.mockRestore() @@ -56,7 +56,7 @@ describe('activateContract', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } mockParseServiceId.mockRestore() @@ -87,7 +87,7 @@ describe('activateContract', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } mockParseServiceId.mockRestore() diff --git a/__tests__/core/contractStartDate.spec.js b/__tests__/core/contractStartDate.spec.js index 6e8aac92090be99a480233965af34394cd338e27..1831c7d754e905207f77a91132bac850cd8057a9 100644 --- a/__tests__/core/contractStartDate.spec.js +++ b/__tests__/core/contractStartDate.spec.js @@ -61,7 +61,7 @@ describe('getContractStartDate', () => { await getContractStartDate() expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) @@ -84,7 +84,7 @@ describe('getContractStartDate', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.NOT_EXISTING_DIRECTORY) + expect(error.message).toBe(errors.NOT_EXISTING_DIRECTORY) } }) }) diff --git a/__tests__/core/contractTermination.spec.js b/__tests__/core/contractTermination.spec.js index db71c233aef34168e62b1462c11e38511f60b608..f65c0be83f0c57022654c2d6641443fdfe662b8b 100644 --- a/__tests__/core/contractTermination.spec.js +++ b/__tests__/core/contractTermination.spec.js @@ -40,7 +40,7 @@ describe('terminateContract', () => { }, }) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) it('should throw VENDOR_DOWN on bad request🚫', async () => { @@ -56,7 +56,7 @@ describe('terminateContract', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) it('should throw VENDOR_DOWN 🚫', async () => { @@ -80,7 +80,7 @@ describe('terminateContract', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) }) diff --git a/__tests__/core/contractVerification.spec.js b/__tests__/core/contractVerification.spec.js index 91228511b10d652b1ba2243dc589c7c0ff8dde9e..f0ddb062c966edba92b894ff046b4a8d29c90059 100644 --- a/__tests__/core/contractVerification.spec.js +++ b/__tests__/core/contractVerification.spec.js @@ -74,7 +74,7 @@ describe('verifyContract', () => { ) expect(serviceId).toBe(78232791) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } mockParseContracts.mockRestore() @@ -126,7 +126,7 @@ describe('verifyContract', () => { ) expect(serviceId).toBe(78232791) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } mockParseContracts.mockRestore() @@ -186,7 +186,7 @@ describe('verifyContract', () => { ) expect(serviceId).toBe(null) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } mockParseContracts.mockRestore() @@ -204,7 +204,7 @@ describe('verifyContract', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } }) it('should return CAPTCHA_RESOLUTION_FAILED if issue in parsing 🚫', async () => { @@ -229,7 +229,7 @@ describe('verifyContract', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.CAPTCHA_RESOLUTION_FAILED) + expect(error.message).toBe(errors.CAPTCHA_RESOLUTION_FAILED) } }) it('should return NULL if no contract are found 🚫', async () => { diff --git a/__tests__/core/findUserAddress.spec.js b/__tests__/core/findUserAddress.spec.js index 683f8ab085bca35297ff20004268bd94038c120e..d17946755caab5b9c69b8890b585dc4993da92a8 100644 --- a/__tests__/core/findUserAddress.spec.js +++ b/__tests__/core/findUserAddress.spec.js @@ -34,7 +34,7 @@ describe('findUserAddress', () => { await findUserAddress() expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) @@ -48,7 +48,7 @@ describe('findUserAddress', () => { await findUserAddress() expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) }) diff --git a/__tests__/core/findUserPdl.spec.js b/__tests__/core/findUserPdl.spec.js index 5ade030d14a1743058cea25029c770c77effc149..746e9d11e5e2a2a0db6fb2227fda74b9b2819a36 100644 --- a/__tests__/core/findUserPdl.spec.js +++ b/__tests__/core/findUserPdl.spec.js @@ -75,7 +75,7 @@ describe('recherchePoint', () => { await findUserPdl() expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.VENDOR_DOWN) + expect(error.message).toBe(errors.VENDOR_DOWN) } }) }) diff --git a/__tests__/core/verifyUserIdentity.spec.js b/__tests__/core/verifyUserIdentity.spec.js index db9d1613944a3e14f319bba431f406e0295cfa98..9563578348063c07c3bd0a005ae37cf6556e2513 100644 --- a/__tests__/core/verifyUserIdentity.spec.js +++ b/__tests__/core/verifyUserIdentity.spec.js @@ -35,7 +35,7 @@ describe('verifyUserIdentity', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.LOGIN_FAILED) + expect(error.message).toBe(errors.LOGIN_FAILED) } }) @@ -56,7 +56,7 @@ describe('verifyUserIdentity', () => { ) expect(true).toBe(false) } catch (error) { - expect(error).toBe(errors.TERMS_VERSION_MISMATCH) + expect(error.message).toBe(errors.TERMS_VERSION_MISMATCH) } }) diff --git a/__tests__/requests/bo.spec.js b/__tests__/requests/bo.spec.js index b4d3f8b366857d912489fb97ee10358c59ea851b..ea0dca564ea26d8e3b0f9e7bbad12400492cc8e2 100644 --- a/__tests__/requests/bo.spec.js +++ b/__tests__/requests/bo.spec.js @@ -58,8 +58,8 @@ describe('Backoffice routes', () => { '69383' ) expect(true).toBe(false) - } catch (e) { - expect(e).toBe(errors.MAINTENANCE) + } catch (error) { + expect(error.message).toBe(errors.MAINTENANCE) } }) }) @@ -122,8 +122,8 @@ describe('Backoffice routes', () => { '123456' ) expect(true).toBe(false) - } catch (e) { - expect(e).toBe(errors.MAINTENANCE) + } catch (error) { + expect(error.message).toBe(errors.MAINTENANCE) } }) }) @@ -161,8 +161,8 @@ describe('Backoffice routes', () => { try { await deleteBoConsent('http://test.com', 'token', 1) expect(true).toBe(false) - } catch (e) { - expect(e).toBe(errors.MAINTENANCE) + } catch (error) { + expect(error.message).toBe(errors.MAINTENANCE) } }) }) @@ -202,8 +202,8 @@ describe('Backoffice routes', () => { inseeCode: '69383', }) expect(true).toBe(false) - } catch (e) { - expect(e).toBe(errors.MAINTENANCE) + } catch (error) { + expect(error.message).toBe(errors.MAINTENANCE) } }) }) diff --git a/__tests__/requests/insee.spec.js b/__tests__/requests/insee.spec.js index 10906459481d629fcaa93701dd1cdeddfbf67d6f..04328916784be41566cbd86567d9c9e8adb44024 100644 --- a/__tests__/requests/insee.spec.js +++ b/__tests__/requests/insee.spec.js @@ -10,7 +10,7 @@ describe('getInseeCode', () => { try { await getInseeCode(69069) } catch (error) { - expect(error).toEqual(errors.USER_ACTION_NEEDED) + expect(error.message).toBe(errors.USER_ACTION_NEEDED) } }) @@ -18,7 +18,7 @@ describe('getInseeCode', () => { try { await getInseeCode(69290) } catch (error) { - expect(error).toEqual(errors.USER_ACTION_NEEDED) + expect(error.message).toBe(errors.USER_ACTION_NEEDED) } }) @@ -54,7 +54,7 @@ describe('getInseeCode', () => { try { await getInseeCode(26600, 'e') } catch (error) { - expect(error).toEqual(errors.USER_ACTION_NEEDED) + expect(error.message).toBe(errors.USER_ACTION_NEEDED) } }) }) diff --git a/src/core/contractActivation.js b/src/core/contractActivation.js index d3352721bb388e50f0d2101017406e9d4a3c561e..e4bb80660f4e0f195104a63c9415fd89c00faf2b 100644 --- a/src/core/contractActivation.js +++ b/src/core/contractActivation.js @@ -44,10 +44,19 @@ async function activateContract( endDate ), }).catch(err => { - log('error', 'commanderCollectePublicationMesures') - log('error', err) - Sentry.captureException('commanderCollectePublicationMesures', err) - throw errors.CAPTCHA_RESOLUTION_FAILED + const errorMessage = `Error while activating contract : ${err}` + log('debug', errorMessage) + Sentry.captureException(errorMessage, { + tags: { + section: 'activateContract', + }, + extra: { + pointId: pointId, + dates: [startDate, endDate], + }, + }) + + throw new Error(errors.CAPTCHA_RESOLUTION_FAILED) }) const parsedReply = await xml2js.parseStringPromise(response.body, { @@ -71,7 +80,7 @@ async function activateContract( // TODO: handle SGT4B8: Il existe déjà plusieurs demandes en cours sur le point ? // TODO: handle SGT4H9: La demande ne porte pas sur un point équipé d'un compteur communicant ouvert aux services niveau 2. // TODO: handle SGT589: La demande ne peut pas aboutir car le compteur n'est actuellement pas téléopérable. - throw errors.CAPTCHA_RESOLUTION_FAILED + throw new Error(errors.CAPTCHA_RESOLUTION_FAILED) } } diff --git a/src/core/contractStartDate.js b/src/core/contractStartDate.js index 8a2eb209466cf2da19702d2fbc6ef95f5bae8971..e51427db013cae8b764ba5f1087fbd1ce613ae5e 100644 --- a/src/core/contractStartDate.js +++ b/src/core/contractStartDate.js @@ -32,8 +32,15 @@ async function getContractStartDate(url, apiAuthKey, userLogin, pointId) { }).catch(err => { const errorMessage = 'Error while fetching contract start date : ' + err log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { + section: 'getContractStartDate', + }, + extra: { + pointId: pointId, + }, + }) + throw new Error(errors.VENDOR_DOWN) }) const result = await xml2js.parseStringPromise(response.body, { @@ -51,7 +58,7 @@ async function getContractStartDate(url, apiAuthKey, userLogin, pointId) { 'error', `Enedis issue ${result.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${result.Envelope.Body.Fault.faultstring}` ) - throw errors.NOT_EXISTING_DIRECTORY + throw new Error(errors.NOT_EXISTING_DIRECTORY) } } diff --git a/src/core/contractTermination.js b/src/core/contractTermination.js index e2a7eb934038368f30966cc441c0ab23729da874..07c333de6bcd2301d5d77f0a8e7ec15e4f465691 100644 --- a/src/core/contractTermination.js +++ b/src/core/contractTermination.js @@ -38,10 +38,19 @@ async function terminateContract( serviceId ), }).catch(err => { - log('error', 'commanderArretServiceSouscritMesures') - log('error', err) - Sentry.captureException('commanderArretServiceSouscritMesures', err) - throw errors.VENDOR_DOWN + const errorMessage = 'Error while terminating contract : ' + err + log('error', errorMessage) + Sentry.captureException(errorMessage, { + tags: { + section: 'terminateContract', + }, + extra: { + contractId: contractId, + pointId: pointId, + serviceId: serviceId, + }, + }) + throw new Error(errors.VENDOR_DOWN) }) const parsedReply = await xml2js.parseStringPromise(response.body, { @@ -64,8 +73,15 @@ async function terminateContract( 'Error while parsing user contract termination: ' + error log('error', errorMessage) log('error', `Enedis issue ${JSON.stringify(parsedReply.Envelope.Body)}`) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { + section: 'terminateContract', + }, + extra: { + pointId: pointId, + }, + }) + throw new Error(errors.VENDOR_DOWN) } } diff --git a/src/core/contractVerification.js b/src/core/contractVerification.js index fddd45fcb5fc0bb18719b1095d576a1df62c0aec..a2242010579dbe0748ae3af8a11d3e982070627a 100644 --- a/src/core/contractVerification.js +++ b/src/core/contractVerification.js @@ -31,10 +31,18 @@ async function verifyContract(url, apiAuthKey, appLogin, contractId, pointId) { headers: sgeHeaders, xml: rechercherServicesSouscritsMesures(appLogin, contractId, pointId), }).catch(err => { - log('error', 'rechercherServicesSouscritsMesures') - log('error', err) - Sentry.captureException('rechercherServicesSouscritsMesures', err) - throw errors.CAPTCHA_RESOLUTION_FAILED + const errorMessage = 'Error while verifying contract : ' + err + log('error', errorMessage) + Sentry.captureException(errorMessage, { + tags: { + section: 'verifyContract', + }, + extra: { + contractId: contractId, + pointId: pointId, + }, + }) + throw new Error(errors.CAPTCHA_RESOLUTION_FAILED) }) const parsedReply = await xml2js.parseStringPromise(response.body, { @@ -66,7 +74,11 @@ async function verifyContract(url, apiAuthKey, appLogin, contractId, pointId) { } catch (error) { const errorMessage = 'Error while parsing user contract: ' + error log('error', errorMessage) - Sentry.captureException(errorMessage) + Sentry.captureException(errorMessage, { + tags: { + section: 'verifyContract', + }, + }) if (parsedReply.Envelope.Body.Fault) { log( 'error', @@ -77,7 +89,7 @@ async function verifyContract(url, apiAuthKey, appLogin, contractId, pointId) { 'error', 'if an error is thrown here, it probably means that the contract has already been open today and that enedis cannot open a second one. Wait until tomorow to try again' ) - throw errors.CAPTCHA_RESOLUTION_FAILED + throw new Error(errors.CAPTCHA_RESOLUTION_FAILED) } } diff --git a/src/core/findUserAddress.js b/src/core/findUserAddress.js index 0f426f21368bb94eb8b6faa36a65039c09c099b9..6882c8c401ac35205de4e17f1a137f5f69a8f249 100644 --- a/src/core/findUserAddress.js +++ b/src/core/findUserAddress.js @@ -32,8 +32,15 @@ async function findUserAddress(url, apiAuthKey, userLogin, pointId) { }).catch(err => { const errorMessage = 'Error while fetching user : ' + err log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { + section: 'findUserAddress', + }, + extra: { + pointId: pointId, + }, + }) + throw new Error(errors.VENDOR_DOWN) }) const result = await xml2js.parseStringPromise(response.body, { @@ -51,8 +58,12 @@ async function findUserAddress(url, apiAuthKey, userLogin, pointId) { 'error', `Enedis issue ${result.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${result.Envelope.Body.Fault.faultstring}` ) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { + section: 'findUserAddress', + }, + }) + throw new Error(errors.VENDOR_DOWN) } } diff --git a/src/core/findUserPdl.js b/src/core/findUserPdl.js index 11bd63525e5cd737a010d45efb5cfa4ba73d4a6d..fd927f86b26303c262f466e875ba333335b09ad8 100644 --- a/src/core/findUserPdl.js +++ b/src/core/findUserPdl.js @@ -44,10 +44,19 @@ async function findUserPdl( escalierEtEtageEtAppartement ), }).catch(err => { - log('error', 'rechercherPointResponse') - log('error', err) - Sentry.captureException('rechercherPointResponse', err) - throw errors.VENDOR_DOWN + const errorMessage = 'Error while finding user pdl : ' + err + log('error', errorMessage) + Sentry.captureException(errorMessage, { + tags: { + section: 'findUserPdl', + }, + extra: { + address: address, + postalCode: postalCode, + escalierEtEtageEtAppartement: escalierEtEtageEtAppartement, + }, + }) + throw new Error(errors.VENDOR_DOWN) }) const parsedReply = await xml2js.parseStringPromise(response.body, { diff --git a/src/core/verifyUserIdentity.js b/src/core/verifyUserIdentity.js index c66697f20d3b47acd0f5322503b0aed897216ac2..3ee35cf94546a6fe9c8961c097e041af294377db 100644 --- a/src/core/verifyUserIdentity.js +++ b/src/core/verifyUserIdentity.js @@ -28,8 +28,8 @@ async function verifyUserIdentity( isAlternateStart = false, inseeCode = '' ) { - // If first start get InseeCode log('debug', 'verifyUserIdentity') + // If first start get InseeCode if (!isAlternateStart) { inseeCode = await getInseeCode(fields.postalCode, fields.city) } @@ -124,7 +124,9 @@ async function verifyUserIdentity( } if (!pdl) { - Sentry.captureException('Second chance failed, no pdl found') + Sentry.captureException('Second chance failed, no pdl found', { + tags: { section: 'verifyUserIdentity' }, + }) } } @@ -132,11 +134,15 @@ async function verifyUserIdentity( log('error', 'PointId does not match') if (isAlternateStart) { - Sentry.captureException('PointId does not match: Alternate start') - throw errors.TERMS_VERSION_MISMATCH + Sentry.captureException('PointId does not match: Alternate start', { + tags: { section: 'verifyUserIdentity' }, + }) + throw new Error(errors.TERMS_VERSION_MISMATCH) } else { - Sentry.captureException('PointId does not match') - throw errors.LOGIN_FAILED + Sentry.captureException('PointId does not match', { + tags: { section: 'verifyUserIdentity' }, + }) + throw new Error(errors.LOGIN_FAILED) } } diff --git a/src/helpers/parsing.js b/src/helpers/parsing.js index 4258c65343fd31a8d5be89a52a910676d7502a10..b3b87c090013ed44f188c698bd5ea84e1c3a03bb 100644 --- a/src/helpers/parsing.js +++ b/src/helpers/parsing.js @@ -1,6 +1,7 @@ // @ts-check const { log } = require('cozy-konnector-libs') const moment = require('moment') +const Sentry = require('@sentry/node') /** * Return User PDL @@ -210,7 +211,16 @@ function parsePointId(pointId) { } else if (strPointId.length === 13) { return `0${strPointId}` } else { - throw new Error(`PointId ${pointId} is malformed`) + const errorMessage = 'PointId is malformed' + Sentry.captureException(errorMessage, { + tags: { + section: 'parsePointId', + }, + extra: { + pointId: pointId, + }, + }) + throw new Error(errorMessage) } } diff --git a/src/index.js b/src/index.js index 85a43c8ddb0b71f3162d3d7b3b7431cc4e9a3485..e094bb399dcd113a402d2019b97d4f98a966d6ef 100644 --- a/src/index.js +++ b/src/index.js @@ -90,6 +90,11 @@ Sentry.init({ * @param {{secret: fields}} cozyParameters */ async function start(fields, cozyParameters) { + const transaction = Sentry.startTransaction({ + op: 'konnector', + name: 'SGE Konnector', + }) + transaction.startChild({ op: 'Konnector starting' }) try { log('info', 'Konnector configuration ...') log('info', `isManual execution: ${manualExecution}`) @@ -100,10 +105,6 @@ async function start(fields, cozyParameters) { 'NO_DATA is enabled, konnector will stop after verifyUserIdentity()' ) } - const transaction = Sentry.startTransaction({ - op: 'konnector', - name: 'SGE Konnector', - }) const pointId = parsePointId(parseInt(fields.pointId)) let baseUrl = fields.wso2BaseUrl @@ -133,8 +134,10 @@ async function start(fields, cozyParameters) { ) { const errorMessage = 'Missing configuration secrets' log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { section: 'start' }, + }) + throw new Error(errors.VENDOR_DOWN) } /** @@ -245,8 +248,10 @@ async function start(fields, cozyParameters) { if (!userConsent) { const errorMessage = 'No user consent found' log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { section: 'start' }, + }) + throw new Error(errors.VENDOR_DOWN) } const consentEndDate = Date.parse(userConsent.endDate) @@ -276,7 +281,16 @@ async function start(fields, cozyParameters) { transaction.finish() log('info', 'Konnector success') } catch (error) { - log('debug', 'error catched in start()', error) + const errorMessage = `SGE konnector encountered an error. Response data: ${JSON.stringify( + error.message + )}` + Sentry.captureMessage(errorMessage, { + tags: { + section: 'start', + }, + }) + transaction.setStatus(Tracing.spanStatusfromHttpCode(409)) + transaction.finish() await Sentry.flush() throw error } @@ -320,14 +334,18 @@ async function deleteConsent( } else { const errorMessage = `No service id retrieved from BO` log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { section: 'start' }, + }) + throw new Error(errors.VENDOR_DOWN) } if (isConsentExpired) { - Sentry.captureException('Consent expired') - throw errors.USER_ACTION_NEEDED_OAUTH_OUTDATED + Sentry.captureException('Consent expired', { + tags: { section: 'start' }, + }) + throw new Error(errors.USER_ACTION_NEEDED_OAUTH_OUTDATED) } - throw errors.TERMS_VERSION_MISMATCH + throw new Error(errors.TERMS_VERSION_MISMATCH) } /** @@ -400,7 +418,9 @@ async function getData(url, apiAuthKey, userLogin, pointId) { }).catch(err => { log('error', 'consultationMesuresDetaillees') log('error', err) - Sentry.captureException('consultationMesuresDetaillees:', err) + Sentry.captureException(`consultationMesuresDetaillees: ${err}`, { + tags: { section: 'getData' }, + }) return err }) @@ -443,7 +463,9 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) { }).catch(err => { log('error', 'getMaxPowerData') log('error', err) - Sentry.captureException('getMaxPowerDate') + Sentry.captureException(`getMaxPowerData: ${err}`, { + tags: { section: 'getMaxPowerData' }, + }) return err }) @@ -496,7 +518,7 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) { // If manual execution, retrieve only 1 week otherwise retrieve 4 weeks const MAX_HISTO = manualExecution ? 1 : 4 - for (var i = 0; i < MAX_HISTO; i++) { + for (let i = 0; i < MAX_HISTO; i++) { log('info', 'launch process with history') const incrementedStartDateString = moment(startLoadDate) .subtract(7 * i, 'day') @@ -519,7 +541,12 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) { }).catch(err => { log('error', 'consultationMesuresDetaillees half-hour') log('error', err) - Sentry.captureException('consultationMesuresDetaillees half-hour') + Sentry.captureException( + `consultationMesuresDetaillees half-hour: ${err}`, + { + tags: { section: 'getDataHalfHour' }, + } + ) return err }) @@ -565,7 +592,9 @@ function processData(doctype = 'com.grandlyon.enedis.day') { } catch (e) { if (doctype === 'com.grandlyon.enedis.minute') { const errorMessage = `No half-hour activated. Issue: ${result.Envelope.Body.Fault.faultstring}` - Sentry.captureMessage(errorMessage) + Sentry.captureMessage(errorMessage, { + tags: { section: 'processData' }, + }) log('warn', errorMessage) } else { log('warn', `Unknown error ${e}`) diff --git a/src/onDeleteAccount.js b/src/onDeleteAccount.js index d2aca6fad15ca353b71b4a6fc29205b147fd6922..68945d07d5b19f339864d5e09e03fbf23a30b636 100644 --- a/src/onDeleteAccount.js +++ b/src/onDeleteAccount.js @@ -12,10 +12,30 @@ const moment = require('moment') require('moment-timezone') const { isLocal, isDev } = require('./helpers/env') const Sentry = require('@sentry/node') +const { version } = require('../package.json') moment.locale('fr') // set the language moment.tz.setDefault('Europe/Paris') // set the timezone +/** + * Sentry + */ +Sentry.init({ + dsn: 'https://18747a93401447f2a81b83cd8c4bbbdf@grandlyon.errors.cozycloud.cc/5', + + // Set tracesSampleRate to 1.0 to capture 100% + // of transactions for performance monitoring. + // We recommend adjusting this value in production + tracesSampleRate: isLocal() ? 0 : 1.0, + release: version, + environment: isDev() ? 'development' : 'production', + debug: isDev(), + integrations: [ + // enable HTTP calls tracing + new Sentry.Integrations.Http({ tracing: true }), + ], +}) + async function onDeleteAccount() { try { log('info', 'Deleting account ...') @@ -69,8 +89,7 @@ async function onDeleteAccount() { } else { const errorMessage = `No service id retrieved from BO` log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + throw new Error(errorMessage) } } @@ -79,8 +98,7 @@ async function onDeleteAccount() { const errorMessage = 'No account revision was found, something went wrong during the deletion of said account' log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + throw new Error(errorMessage) } } catch (error) { log('debug', 'error catched in onDeleteAccount()', error) @@ -98,8 +116,10 @@ onDeleteAccount().then( err => { const errorMessage = `onDeleteAccount: An error occurred during script: ${err.message}` log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.VENDOR_DOWN + Sentry.captureException(errorMessage, { + tags: { section: 'onDeleteAccount' }, + }) + throw new Error(errors.VENDOR_DOWN) } ) diff --git a/src/requests/bo.js b/src/requests/bo.js index 7b938edf4b895e5d1bd0cbe1b53cde5ea5b86f26..aeb01656f3b8e315fc605d9200e9c4c4cac33485 100644 --- a/src/requests/bo.js +++ b/src/requests/bo.js @@ -49,11 +49,19 @@ async function createBoConsent( headers ) return data - } catch (e) { - const errorMessage = `BO replied with ${e}` + } catch (err) { + const errorMessage = 'Error while creating BO consent : ' + err log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.MAINTENANCE + Sentry.captureException(errorMessage, { + tags: { + section: 'createBoConsent', + }, + extra: { + pointID: pointID, + safetyOnBoarding: safetyOnBoarding, + }, + }) + throw new Error(errors.MAINTENANCE) } } @@ -72,11 +80,11 @@ async function updateBoConsent(url, token, consent, serviceId) { }, } + let consentId = '' + if (consent.ID) { + consentId = consent.ID.toString() + } try { - let consentId = '' - if (consent.ID) { - consentId = consent.ID.toString() - } const { data } = await axios.put( `${url}/consent/${consentId}`, { @@ -86,33 +94,47 @@ async function updateBoConsent(url, token, consent, serviceId) { headers ) return data - } catch (e) { - const errorMessage = `BO replied with ${e}` + } catch (err) { + const errorMessage = 'Error while updating BO consent : ' + err log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.MAINTENANCE + Sentry.captureException(errorMessage, { + tags: { + section: 'updateBoConsent', + }, + extra: { + consentId: consentId, + }, + }) + throw new Error(errors.MAINTENANCE) } } /** - * @param {number} boId + * @param {number} consentId * @returns {Promise<Consent>} */ -async function getBoConsent(url, token, boId) { - log('info', `Query getBoConsent ${boId}`) +async function getBoConsent(url, token, consentId) { + log('info', `Query getBoConsent ${consentId}`) const headers = { headers: { Authorization: `Bearer ${token}`, }, } try { - const { data } = await axios.get(`${url}/consent/${boId}`, headers) + const { data } = await axios.get(`${url}/consent/${consentId}`, headers) return data - } catch (e) { - const errorMessage = `BO replied with ${e}` + } catch (err) { + const errorMessage = 'Error while getting BO consent : ' + err log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.MAINTENANCE + Sentry.captureException(errorMessage, { + tags: { + section: 'getBoConsent', + }, + extra: { + consentId: consentId, + }, + }) + throw new Error(errors.MAINTENANCE) } } @@ -120,24 +142,31 @@ async function getBoConsent(url, token, boId) { * Delete BO consent * @param {string} url * @param {string} token - * @param {number} boId + * @param {number} consentId * @returns */ -async function deleteBoConsent(url, token, boId) { - log('info', `Query deleteBoConsent ${boId}`) +async function deleteBoConsent(url, token, consentId) { + log('info', `Query deleteBoConsent ${consentId}`) const headers = { headers: { Authorization: `Bearer ${token}`, }, } try { - const { data } = await axios.delete(`${url}/consent/${boId}`, headers) + const { data } = await axios.delete(`${url}/consent/${consentId}`, headers) return data - } catch (e) { - const errorMessage = `BO replied with ${e}` + } catch (err) { + const errorMessage = 'Error while deleting BO consent : ' + err log('error', errorMessage) - Sentry.captureException(errorMessage) - throw errors.MAINTENANCE + Sentry.captureException(errorMessage, { + tags: { + section: 'deleteBoConsent', + }, + extra: { + consentId: consentId, + }, + }) + throw new Error(errors.MAINTENANCE) } } diff --git a/src/requests/insee.js b/src/requests/insee.js index 3663d3cea9f40f329138e89d13dd12a25a41e5bc..e8c22af8824f5fa758d5a25880dbb352b29ea3e5 100644 --- a/src/requests/insee.js +++ b/src/requests/insee.js @@ -46,7 +46,7 @@ async function getInseeCode(postalCode, city) { log('error', error.message) const errorMessage = `Query getInseeCode failed for postalCode ${postalCode} / ${city}` Sentry.captureException(errorMessage) - throw errors.USER_ACTION_NEEDED + throw new Error(errors.USER_ACTION_NEEDED) } }