From bece5a1c50434b9a9dc7a5f12aa771c432860089 Mon Sep 17 00:00:00 2001
From: Philip <42116482+PhilipAbed@users.noreply.github.com>
Date: Tue, 31 Oct 2023 15:46:55 +0200
Subject: [PATCH] refactor(errors): massaging validation messages before we
 assign it (#25452)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/config/migrations/custom/host-rules-migration.ts |  3 ++-
 lib/config/secrets.ts                                |  2 +-
 lib/util/git/error.ts                                | 11 ++++++-----
 lib/util/git/index.ts                                |  2 +-
 lib/util/package-rules/index.spec.ts                 |  4 ++--
 lib/util/package-rules/merge-confidence.ts           |  5 +++--
 lib/workers/repository/error-config.spec.ts          |  2 +-
 lib/workers/repository/error-config.ts               |  6 +-----
 lib/workers/repository/init/merge.ts                 | 10 ++++++++--
 lib/workers/repository/process/index.ts              |  2 +-
 10 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/lib/config/migrations/custom/host-rules-migration.ts b/lib/config/migrations/custom/host-rules-migration.ts
index b773828813..bcf064fe13 100644
--- a/lib/config/migrations/custom/host-rules-migration.ts
+++ b/lib/config/migrations/custom/host-rules-migration.ts
@@ -77,7 +77,8 @@ function validateHostRule(rule: LegacyHostRule & HostRule): void {
     if (distinctHostValues.size > 1) {
       const error = new Error(CONFIG_VALIDATION);
       error.validationSource = 'config';
-      error.validationMessage = `hostRules cannot contain more than one host-matching field - use "matchHost" only.`;
+      error.validationMessage =
+        '`hostRules` cannot contain more than one host-matching field - use `matchHost` only.';
       error.validationError =
         'The renovate configuration file contains some invalid settings';
       throw error;
diff --git a/lib/config/secrets.ts b/lib/config/secrets.ts
index 3198a99b32..874afe29a7 100644
--- a/lib/config/secrets.ts
+++ b/lib/config/secrets.ts
@@ -66,7 +66,7 @@ function replaceSecretsInString(
     const error = new Error(CONFIG_VALIDATION);
     error.validationSource = 'config';
     error.validationError = 'Disallowed secret substitution';
-    error.validationMessage = `The field ${key} may not use secret substitution`;
+    error.validationMessage = `The field \`${key}\` may not use secret substitution`;
     throw error;
   }
   return value.replace(secretTemplateRegex, (_, secretName) => {
diff --git a/lib/util/git/error.ts b/lib/util/git/error.ts
index cd9e80e21d..34708669f3 100644
--- a/lib/util/git/error.ts
+++ b/lib/util/git/error.ts
@@ -63,7 +63,7 @@ export function checkForPlatformFailure(err: Error): Error | null {
       logger.debug({ err }, 'Converting git error to CONFIG_VALIDATION error');
       const res = new Error(CONFIG_VALIDATION);
       res.validationError = message;
-      res.validationMessage = err.message;
+      res.validationMessage = `\`${err.message.replaceAll('`', "'")}\``;
       return res;
     }
   }
@@ -82,7 +82,7 @@ export function handleCommitError(
     const error = new Error(CONFIG_VALIDATION);
     error.validationSource = 'None';
     error.validationError = 'An existing branch is blocking Renovate';
-    error.validationMessage = `Renovate needs to create the branch "${branchName}" but is blocked from doing so because of an existing branch called "renovate". Please remove it so that Renovate can proceed.`;
+    error.validationMessage = `Renovate needs to create the branch \`${branchName}\` but is blocked from doing so because of an existing branch called \`renovate\`. Please remove it so that Renovate can proceed.`;
     throw error;
   }
   if (
@@ -114,9 +114,10 @@ export function handleCommitError(
     const error = new Error(CONFIG_VALIDATION);
     error.validationSource = branchName;
     error.validationError = 'Bitbucket committer error';
-    error.validationMessage = `Renovate has experienced the following error when attempting to push its branch to the server: "${String(
-      err.message
-    )}"`;
+    error.validationMessage = `Renovate has experienced the following error when attempting to push its branch to the server: \`${err.message.replaceAll(
+      '`',
+      "'"
+    )}\``;
     throw error;
   }
   if (err.message.includes('remote: error: cannot lock ref')) {
diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index c919e559ef..ce68362dc9 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -286,7 +286,7 @@ export function setGitAuthor(gitAuthor: string | undefined): void {
     const error = new Error(CONFIG_VALIDATION);
     error.validationSource = 'None';
     error.validationError = 'Invalid gitAuthor';
-    error.validationMessage = `gitAuthor is not parsed as valid RFC5322 format: ${gitAuthor!}`;
+    error.validationMessage = `\`gitAuthor\` is not parsed as valid RFC5322 format: \`${gitAuthor!}\``;
     throw error;
   }
   config.gitAuthorName = gitAuthorParsed.name;
diff --git a/lib/util/package-rules/index.spec.ts b/lib/util/package-rules/index.spec.ts
index 195425fa02..34a70e8fd8 100644
--- a/lib/util/package-rules/index.spec.ts
+++ b/lib/util/package-rules/index.spec.ts
@@ -732,8 +732,8 @@ describe('util/package-rules/index', () => {
       }
 
       expect(error).toStrictEqual(new Error(MISSING_API_CREDENTIALS));
-      expect(error.validationMessage).toBe('Missing credentials');
-      expect(error.validationError).toBe(
+      expect(error.validationError).toBe('Missing credentials');
+      expect(error.validationMessage).toBe(
         'The `matchConfidence` matcher in `packageRules` requires authentication. Please refer to the [documentation](https://docs.renovatebot.com/configuration-options/#matchconfidence) and add the required host rule.'
       );
     });
diff --git a/lib/util/package-rules/merge-confidence.ts b/lib/util/package-rules/merge-confidence.ts
index 9836892f49..edd87429b8 100644
--- a/lib/util/package-rules/merge-confidence.ts
+++ b/lib/util/package-rules/merge-confidence.ts
@@ -18,8 +18,9 @@ export class MergeConfidenceMatcher extends Matcher {
      */
     if (is.undefined(getApiToken())) {
       const error = new Error(MISSING_API_CREDENTIALS);
-      error.validationMessage = 'Missing credentials';
-      error.validationError =
+      error.validationSource = 'MatchConfidence Authenticator';
+      error.validationError = 'Missing credentials';
+      error.validationMessage =
         'The `matchConfidence` matcher in `packageRules` requires authentication. Please refer to the [documentation](https://docs.renovatebot.com/configuration-options/#matchconfidence) and add the required host rule.';
       throw error;
     }
diff --git a/lib/workers/repository/error-config.spec.ts b/lib/workers/repository/error-config.spec.ts
index 7731fb58c2..b37abdd4be 100644
--- a/lib/workers/repository/error-config.spec.ts
+++ b/lib/workers/repository/error-config.spec.ts
@@ -34,7 +34,7 @@ describe('workers/repository/error-config', () => {
 
 Location: \`package.json\`
 Error type: some-error
-Message: \`some-message\`
+Message: some-message
 `;
       const error = new Error(CONFIG_VALIDATION);
       error.validationSource = 'package.json';
diff --git a/lib/workers/repository/error-config.ts b/lib/workers/repository/error-config.ts
index f7b62dda01..24f04c4e3a 100644
--- a/lib/workers/repository/error-config.ts
+++ b/lib/workers/repository/error-config.ts
@@ -3,7 +3,6 @@ import { GlobalConfig } from '../../config/global';
 import type { RenovateConfig } from '../../config/types';
 import { logger } from '../../logger';
 import { Pr, platform } from '../../modules/platform';
-import { regEx } from '../../util/regex';
 
 export function raiseConfigWarningIssue(
   config: RenovateConfig,
@@ -42,10 +41,7 @@ async function raiseWarningIssue(
     body += `Error type: ${error.validationError}\n`;
   }
   if (error.validationMessage) {
-    body += `Message: \`${error.validationMessage.replace(
-      regEx(/`/g),
-      "'"
-    )}\`\n`;
+    body += `Message: ${error.validationMessage}\n`;
   }
 
   const pr = await platform.getBranchPr(
diff --git a/lib/workers/repository/init/merge.ts b/lib/workers/repository/init/merge.ts
index a244b768ae..a0233d22e5 100644
--- a/lib/workers/repository/init/merge.ts
+++ b/lib/workers/repository/init/merge.ts
@@ -140,7 +140,10 @@ export async function detectRepoFileConfig(): Promise<RepoFileConfig> {
           'Error parsing renovate config renovate.json5'
         );
         const validationError = 'Invalid JSON5 (parsing failed)';
-        const validationMessage = `JSON5.parse error:  ${String(err.message)}`;
+        const validationMessage = `JSON5.parse error: \`${err.message.replaceAll(
+          '`',
+          "'"
+        )}\``;
         return {
           configFileName,
           configFileParseError: { validationError, validationMessage },
@@ -181,7 +184,10 @@ export async function detectRepoFileConfig(): Promise<RepoFileConfig> {
           'Error parsing renovate config'
         );
         const validationError = 'Invalid JSON (parsing failed)';
-        const validationMessage = `JSON.parse error:  ${String(err.message)}`;
+        const validationMessage = `JSON.parse error:  \`${err.message.replaceAll(
+          '`',
+          "'"
+        )}\``;
         return {
           configFileName,
           configFileParseError: { validationError, validationMessage },
diff --git a/lib/workers/repository/process/index.ts b/lib/workers/repository/process/index.ts
index 39b8e76fa8..ff10492c10 100644
--- a/lib/workers/repository/process/index.ts
+++ b/lib/workers/repository/process/index.ts
@@ -56,7 +56,7 @@ async function getBaseBranchConfig(
       const error = new Error(CONFIG_VALIDATION);
       error.validationSource = 'config';
       error.validationError = 'Error fetching config file';
-      error.validationMessage = `Error fetching config file ${configFileName} from branch ${baseBranch}`;
+      error.validationMessage = `Error fetching config file \`${configFileName}\` from branch \`${baseBranch}\``;
       throw error;
     }
 
-- 
GitLab