From 4d136760816e44b552ab5e193a141afc428d99fb Mon Sep 17 00:00:00 2001 From: Ron Nathaniel <45116635+ronnathaniel@users.noreply.github.com> Date: Tue, 21 Jun 2022 13:12:10 -0400 Subject: [PATCH] fix(utils): updated regex match and made failed matches safer (#599) --- src/config.js | 4 ++++ src/utils.js | 29 +++++++++++++---------- test/unit_tests/test_config.js | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/config.js b/src/config.js index 51f56653..aac85bf7 100644 --- a/src/config.js +++ b/src/config.js @@ -241,6 +241,10 @@ module.exports.setConfig = function setConfig(configData) { config.disableHttpResponseBodyCapture = configData.disableHttpResponseBodyCapture; } + if (configData.allowErrMessageStatus) { + config.allowErrMessageStatus = configData.allowErrMessageStatus; + } + // Keys to automatically capture and label if (configData.keysToAllow) { config.keysToAllow = module.exports.prepareMatchingKeys(configData.keysToAllow); diff --git a/src/utils.js b/src/utils.js index 355137c8..0ef6c7ce 100644 --- a/src/utils.js +++ b/src/utils.js @@ -208,19 +208,24 @@ function distinct(arr) { * Attempt to extract an HTTP Status Code from a String. * Matches and returns only 3-digit numbers in range 2XX-5XX. * @param {String} message A String containing a Status Code. - * @return {Number} extracted Status Code. If not found -> 0, the only falsy Number. - */ -function extractStatusCode(message) { - // matches a [Non-Digit], [2xx - 5xx], and a [Non-Digit]. globally & multiline. - // \D ([2-5]\d{2}) \D /g m - const statusCodeMatch = /\D([2-5]\d{2})\D/gm; - const statusCodes = message - .match(statusCodeMatch) - .map(m => m.replace(statusCodeMatch, '$1')); - if (statusCodes && statusCodes.length) { - return Number(statusCodes[0]); + * @param {Number} defaultCode The defaulting Status Code if none are found. + * 0 is chosen as the only falsy Number to avoid being added. + * @return {Number} extracted Status Code. + */ +function extractStatusCode(message, defaultCode = 0) { + // matches a [Non-Digit or SOL], [2xx - 5xx], and a [Non-Digit or EOL]. globally & multiline. + // (?:^|\D) ([2-5]\d{2}) (?:$|\D) /g m + const statusCodeMatch = /(?:^|\D)([2-5]\d{2})(?:$|\D)/gm; + const matches = message + .match(statusCodeMatch); + if (matches === null || !matches.length) { + debugLog('Could not extract Status Code from Message:', message); + debugLog('Defaulting Status to', defaultCode); + return defaultCode; } - return 0; + const statusCodes = matches + .map(m => m.replace(statusCodeMatch, '$1')); + return Number(statusCodes[0]); } module.exports.createTimestampFromTime = createTimestampFromTime; diff --git a/test/unit_tests/test_config.js b/test/unit_tests/test_config.js index 49bb3040..7b42c852 100644 --- a/test/unit_tests/test_config.js +++ b/test/unit_tests/test_config.js @@ -1,6 +1,7 @@ const { expect } = require('chai'); const consts = require('../../src/consts.js'); const config = require('../../src/config.js'); +const utils = require('../../src/utils.js'); describe('tracer config tests', () => { @@ -117,6 +118,47 @@ describe('tracer config tests', () => { expect(config.getConfig()).to.contain({ decodeHTTP: false }); }); + it('setConfig: set allowErrMessageStatus to true', () => { + config.setConfig({ allowErrMessageStatus: true }); + expect(config.getConfig()).to.contain({ allowErrMessageStatus: true }); + }); + + it('setConfig: set allowErrMessageStatus and match error message', () => { + config.setConfig({ allowErrMessageStatus: true }); + + const testCode = 324; + [ + `{errorMessage: TEST-MESSAGE, statusCode: ${testCode}}`, + `errorMessage: TEST-MESSAGE, statusCode: ${testCode}`, + `{statusCode:${testCode}}`, + `{statusCode:${testCode}}`, + `Error - ${testCode}`, + `${testCode}`, + `${testCode}: errorMessage`, + `${testCode} - error has a message`, + ] + .forEach((m) => { + const statusCode = utils.extractStatusCode(m); + expect(statusCode).to.be.equal(testCode); + }); + }); + + it('setConfig: set allowErrMessageStatus without matches', () => { + config.setConfig({ allowErrMessageStatus: true }); + + const defaultStatusCode = 900; + [ + 'test message', + 'No Status Code Found', + '4123 is not a Status Code', + '22 is also not one.', + ] + .forEach((m) => { + const statusCode = utils.extractStatusCode(m, defaultStatusCode); + expect(statusCode).to.be.equal(defaultStatusCode); + }); + }); + it('setConfig: set addReturnValue to false', () => { config.setConfig({ addReturnValue: false }); expect(config.getConfig()).to.contain({ addReturnValue: false });