diff --git a/src/core/contractActivation.js b/src/core/contractActivation.js index 465d6ef87052cebc264c844d0cac4f2f5188c44e..6a93c62af8fb859675670e1b10a4ec7c3f067082 100644 --- a/src/core/contractActivation.js +++ b/src/core/contractActivation.js @@ -5,6 +5,7 @@ const { parseTags, parseValue, parseServiceId } = require('../helpers/parsing') const { commanderCollectePublicationMesures } = require('../requests/sge') const xml2js = require('xml2js') const Sentry = require('@sentry/node') +const { catchRequestReject } = require('../helpers/catch') /** * @param {string} url @@ -59,6 +60,8 @@ async function activateContract( throw new Error(errors.CAPTCHA_RESOLUTION_FAILED) }) + catchRequestReject(response.body) + const parsedReply = await xml2js.parseStringPromise(response.body, { tagNameProcessors: [parseTags], valueProcessors: [parseValue], diff --git a/src/core/contractTermination.js b/src/core/contractTermination.js index 663278bcdaf42fd0ea0b922afae44b8b8e82894b..39862c17c4b3bec37fb27acfe307aa8f002bca5c 100644 --- a/src/core/contractTermination.js +++ b/src/core/contractTermination.js @@ -5,6 +5,7 @@ const { parseTags, parseValue } = require('../helpers/parsing') const { commanderArretServiceSouscritMesures } = require('../requests/sge') const xml2js = require('xml2js') const Sentry = require('@sentry/node') +const { catchRequestReject } = require('../helpers/catch') /** * @param {string} url @@ -53,6 +54,8 @@ async function terminateContract( throw new Error(errors.VENDOR_DOWN) }) + catchRequestReject(response.body) + const parsedReply = await xml2js.parseStringPromise(response.body, { tagNameProcessors: [parseTags], valueProcessors: [parseValue], diff --git a/src/core/contractVerification.js b/src/core/contractVerification.js index bb3591101b7b130717cb04e455a5a021d702138d..db53cb53e37f1d7716dec5941296bcea3c3a0bc6 100644 --- a/src/core/contractVerification.js +++ b/src/core/contractVerification.js @@ -11,6 +11,7 @@ const { rechercherServicesSouscritsMesures } = require('../requests/sge') const xml2js = require('xml2js') const { contractState } = require('./types/enum') const Sentry = require('@sentry/node') +const { catchRequestReject } = require('../helpers/catch') /** * @param {string} url @@ -45,6 +46,8 @@ async function verifyContract(url, apiAuthKey, appLogin, contractId, pointId) { throw new Error(errors.CAPTCHA_RESOLUTION_FAILED) }) + catchRequestReject(response.body) + const parsedReply = await xml2js.parseStringPromise(response.body, { tagNameProcessors: [parseTags], valueProcessors: [parseValue], diff --git a/src/core/findUserAddress.js b/src/core/findUserAddress.js index 4f7b51d924ad6919fdf9c3c1a30473fab2a6220b..f5b5465729343e03b1ae7d40e6e59b3743f7c679 100644 --- a/src/core/findUserAddress.js +++ b/src/core/findUserAddress.js @@ -9,6 +9,7 @@ const { const xml2js = require('xml2js') const { consulterDonneesTechniquesContractuelles } = require('../requests/sge') const Sentry = require('@sentry/node') +const { catchRequestReject } = require('../helpers/catch') /** * Get user contract start date @@ -43,6 +44,8 @@ async function findUserAddress(url, apiAuthKey, userLogin, pointId) { throw new Error(errors.VENDOR_DOWN) }) + catchRequestReject(response.body) + const result = await xml2js.parseStringPromise(response.body, { tagNameProcessors: [parseTags], valueProcessors: [parseValue], diff --git a/src/core/findUserPdl.js b/src/core/findUserPdl.js index 137a8cc3416d70b63c4c9e1032e65269f06c8fbf..5ad83f8daaee310e1876235c3f5a5ac2338ff1b8 100644 --- a/src/core/findUserPdl.js +++ b/src/core/findUserPdl.js @@ -5,6 +5,7 @@ const { parseUserPdl, parseTags, parseValue } = require('../helpers/parsing') const { rechercherPoint } = require('../requests/sge') const xml2js = require('xml2js') const Sentry = require('@sentry/node') +const { catchRequestReject } = require('../helpers/catch') /** * @param {string} url @@ -60,12 +61,17 @@ async function findUserPdl( throw new Error(errors.VENDOR_DOWN) }) - const parsedReply = await xml2js.parseStringPromise(response.body, { - tagNameProcessors: [parseTags], - valueProcessors: [parseValue], - explicitArray: false, - }) + catchRequestReject(response.body) + const parsedReply = await xml2js + .parseStringPromise(response.body, { + tagNameProcessors: [parseTags], + valueProcessors: [parseValue], + explicitArray: false, + }) + .catch(error => { + log('error', 'Error while parsing XML: ' + error) + }) try { return parseUserPdl(parsedReply) } catch (error) { diff --git a/src/helpers/catch.js b/src/helpers/catch.js new file mode 100644 index 0000000000000000000000000000000000000000..7598f65d1d5f1a2f6d5cebb155bbf07762d01713 --- /dev/null +++ b/src/helpers/catch.js @@ -0,0 +1,18 @@ +const { log, errors } = require('cozy-konnector-libs') + +/** + * Throw a VENDOR_DOWN error if the response contains a "Request Rejected" + * Enedis might send a 429 status but the F5 always transform it to a 200 + * @param {string} response + * @example <html><head><title>Request Rejected</title></head> + * <body>The requested URL was rejected. Please consult with your administrator</body></html> + */ +function catchRequestReject(response) { + if (response.includes('Request Rejected')) { + log('debug', response.slice(0, 100)) + log('error', 'Request Rejected') + throw new Error(errors.VENDOR_DOWN) + } +} + +module.exports = { catchRequestReject } diff --git a/src/index.js b/src/index.js index 5ddd206c06f7c717b791ac2734aef76a4f3cc7ea..04c366d5e6dbb60fac675cf2cd17b0ce0cacbe0f 100644 --- a/src/index.js +++ b/src/index.js @@ -43,6 +43,7 @@ const Sentry = require('@sentry/node') // eslint-disable-next-line const Tracing = require('@sentry/tracing') // Needed for tracking performance in Sentry const { version } = require('../package.json') +const { catchRequestReject } = require('./helpers/catch') moment.locale('fr') // set the language moment.tz.setDefault('Europe/Paris') // set the timezone @@ -398,6 +399,8 @@ async function getOffPeakHours(url, apiAuthKey, userLogin, pointId) { return err }) + catchRequestReject(response.body) + const result = await xml2js.parseStringPromise(response.body, { tagNameProcessors: [parseTags], valueProcessors: [parseValue], @@ -426,14 +429,14 @@ async function getOffPeakHours(url, apiAuthKey, userLogin, pointId) { } /** - * Get hour data + * Get daily data * @param {string} url * @param {string} apiAuthKey * @param {string} userLogin * @param {string} pointId */ async function getData(url, apiAuthKey, userLogin, pointId) { - log('info', 'Fetching data') + log('info', 'Fetching daily data') const sgeHeaders = { 'Content-Type': 'text/xml;charset=UTF-8', apikey: apiAuthKey, @@ -459,6 +462,8 @@ async function getData(url, apiAuthKey, userLogin, pointId) { return err }) + catchRequestReject(response.body) + xml2js.parseString( response.body, { @@ -502,6 +507,8 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) { return err }) + catchRequestReject(response.body) + xml2js.parseString( response.body, { @@ -521,7 +528,7 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) { * @param {string} pointId */ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) { - log('info', 'Fetching data') + log('info', 'Fetching half-hour data') const sgeHeaders = { 'Content-Type': 'text/xml;charset=UTF-8', apikey: apiAuthKey, @@ -562,6 +569,8 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) { return err }) + catchRequestReject(response.body) + xml2js.parseString( response.body, { @@ -579,7 +588,7 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) { * @param {string} doctype * @returns */ -function processData(doctype = 'com.grandlyon.enedis.day') { +function processData(doctype) { return async (err, result) => { if (err) { log('error', err) @@ -587,7 +596,7 @@ function processData(doctype = 'com.grandlyon.enedis.day') { throw err } // Return only needed part of info - log('info', doctype) + log('info', `Processing ${doctype} data`) try { const data = parseSgeXmlData(result) const processedDailyData = await storeData( @@ -595,8 +604,6 @@ function processData(doctype = 'com.grandlyon.enedis.day') { doctype, ['year', 'month', 'day', 'hour', 'minute'] ) - - log('info', 'Aggregate enedis daily data for month and year') if (doctype === 'com.grandlyon.enedis.day') { log('info', 'Aggregating...') await aggregateMonthAndYearData(processedDailyData)