From c8f1397fcb39a398bd71cb79aff0639139bdea85 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Fri, 17 Mar 2023 16:55:04 +0100 Subject: [PATCH 1/6] Refactored the error message parser This is just a refactoring of the error parsing mechanism on the frontend --- .../javascripts/lib/utils/error_message.js | 22 +--- .../security_configuration/components/app.vue | 3 +- .../sast/components/app.vue | 12 +- spec/frontend/lib/utils/error_message_spec.js | 116 ++++++++---------- 4 files changed, 62 insertions(+), 91 deletions(-) diff --git a/app/assets/javascripts/lib/utils/error_message.js b/app/assets/javascripts/lib/utils/error_message.js index 4cea4257e7b6ee..3984883dbf7f56 100644 --- a/app/assets/javascripts/lib/utils/error_message.js +++ b/app/assets/javascripts/lib/utils/error_message.js @@ -1,20 +1,8 @@ export const USER_FACING_ERROR_MESSAGE_PREFIX = 'UF:'; -const getMessageFromError = (error = '') => { - return error.message || error; -}; - -export const parseErrorMessage = (error = '') => { - const messageString = getMessageFromError(error); - - if (messageString.startsWith(USER_FACING_ERROR_MESSAGE_PREFIX)) { - return { - message: messageString.replace(USER_FACING_ERROR_MESSAGE_PREFIX, '').trim(), - userFacing: true, - }; - } - return { - message: messageString, - userFacing: false, - }; +export const parseErrorMessage = (error = '', defaultMessage = '') => { + const messageString = typeof error === 'string' ? error : error.message || ''; + return messageString.startsWith(USER_FACING_ERROR_MESSAGE_PREFIX) + ? messageString.replace(USER_FACING_ERROR_MESSAGE_PREFIX, '').trim() + : defaultMessage; }; diff --git a/app/assets/javascripts/security_configuration/components/app.vue b/app/assets/javascripts/security_configuration/components/app.vue index ccfaa678201a0d..3f1d66f17e0309 100644 --- a/app/assets/javascripts/security_configuration/components/app.vue +++ b/app/assets/javascripts/security_configuration/components/app.vue @@ -129,8 +129,7 @@ export default { this.autoDevopsEnabledAlertDismissedProjects = Array.from(dismissedProjects); }, onError(error) { - const { message, userFacing } = parseErrorMessage(error); - this.errorMessage = userFacing ? message : i18n.genericErrorText; + this.errorMessage = parseErrorMessage(error, i18n.genericErrorText); }, dismissAlert() { this.errorMessage = ''; diff --git a/ee/app/assets/javascripts/security_configuration/sast/components/app.vue b/ee/app/assets/javascripts/security_configuration/sast/components/app.vue index 35ee1b17a362d5..58024acd16b4d3 100644 --- a/ee/app/assets/javascripts/security_configuration/sast/components/app.vue +++ b/ee/app/assets/javascripts/security_configuration/sast/components/app.vue @@ -74,21 +74,13 @@ export default { sastCiConfiguration: null, hasLoadingError: false, specificErrorText: undefined, + errorText: '', }; }, - computed: { - errorText() { - return this.specificErrorText || this.$options.i18n.genericErrorText; - }, - }, methods: { onError(error) { this.hasLoadingError = true; - const { message, userFacing } = parseErrorMessage(error); - - if (userFacing) { - this.specificErrorText = message; - } + this.errorText = parseErrorMessage(error, this.$options.i18n.genericErrorText); }, }, feedbackIssue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/225991', diff --git a/spec/frontend/lib/utils/error_message_spec.js b/spec/frontend/lib/utils/error_message_spec.js index 17b5168c32f417..d1cfa78044fcc1 100644 --- a/spec/frontend/lib/utils/error_message_spec.js +++ b/spec/frontend/lib/utils/error_message_spec.js @@ -1,65 +1,57 @@ import { parseErrorMessage, USER_FACING_ERROR_MESSAGE_PREFIX } from '~/lib/utils/error_message'; -const defaultErrorMessage = 'Something caused this error'; -const userFacingErrorMessage = 'User facing error message'; -const nonUserFacingErrorMessage = 'NonUser facing error message'; -const genericErrorMessage = 'Some error message'; - -describe('error message', () => { - describe('when given an errormessage object', () => { - const errorMessageObject = { - options: { - cause: defaultErrorMessage, - }, - filename: 'error.js', - linenumber: 7, - }; - - it('returns the correct values for userfacing errors', () => { - const userFacingObject = errorMessageObject; - userFacingObject.message = `${USER_FACING_ERROR_MESSAGE_PREFIX} ${userFacingErrorMessage}`; - - expect(parseErrorMessage(userFacingObject)).toEqual({ - message: userFacingErrorMessage, - userFacing: true, - }); - }); - - it('returns the correct values for non userfacing errors', () => { - const nonUserFacingObject = errorMessageObject; - nonUserFacingObject.message = nonUserFacingErrorMessage; - - expect(parseErrorMessage(nonUserFacingObject)).toEqual({ - message: nonUserFacingErrorMessage, - userFacing: false, - }); - }); - }); - - describe('when given an errormessage string', () => { - it('returns the correct values for userfacing errors', () => { - expect( - parseErrorMessage(`${USER_FACING_ERROR_MESSAGE_PREFIX} ${genericErrorMessage}`), - ).toEqual({ - message: genericErrorMessage, - userFacing: true, - }); - }); - - it('returns the correct values for non userfacing errors', () => { - expect(parseErrorMessage(genericErrorMessage)).toEqual({ - message: genericErrorMessage, - userFacing: false, - }); - }); - }); - - describe('when given nothing', () => { - it('returns an empty error message', () => { - expect(parseErrorMessage()).toEqual({ - message: '', - userFacing: false, - }); - }); - }); +const defaultErrorMessage = 'Default error message'; +const errorMessage = 'Returned error message'; + +const generateErrorWithMessage = (message) => { + return { + message, + }; +}; + +describe('parseErrorMessage', () => { + it.each` + error | expectedResult + ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${errorMessage} + ${`${errorMessage} ${USER_FACING_ERROR_MESSAGE_PREFIX}`} | ${defaultErrorMessage} + ${errorMessage} | ${defaultErrorMessage} + ${undefined} | ${defaultErrorMessage} + ${''} | ${defaultErrorMessage} + `( + 'properly parses "$error" error string and returns "$expectedResult"', + ({ error, expectedResult }) => { + expect(parseErrorMessage(error, defaultErrorMessage)).toEqual(expectedResult); + }, + ); + + it.each` + error | expectedResult + ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${errorMessage} + ${`${errorMessage} ${USER_FACING_ERROR_MESSAGE_PREFIX}`} | ${defaultErrorMessage} + ${errorMessage} | ${defaultErrorMessage} + ${undefined} | ${defaultErrorMessage} + ${''} | ${defaultErrorMessage} + `( + 'properly parses "$error" error object and returns "$expectedResult"', + ({ error, expectedResult }) => { + const errorObject = generateErrorWithMessage(error); + expect(parseErrorMessage(errorObject, defaultErrorMessage)).toEqual(expectedResult); + }, + ); + + it.each` + error | defaultMessage | expectedResult + ${undefined} | ${defaultErrorMessage} | ${defaultErrorMessage} + ${''} | ${defaultErrorMessage} | ${defaultErrorMessage} + ${{}} | ${defaultErrorMessage} | ${defaultErrorMessage} + ${errorMessage} | ${undefined} | ${''} + ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${undefined} | ${errorMessage} + ${errorMessage} | ${''} | ${''} + ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${''} | ${errorMessage} + `( + 'properly handles the edge case of error="$error" and defaultMessage="$defaultMessage"', + ({ error, defaultMessage, expectedResult }) => { + expect(parseErrorMessage(error, defaultMessage)).toEqual(expectedResult); + }, + ); }); -- GitLab From 21b3d083b83116bf0697561bd9c7a94152fa70b7 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Fri, 17 Mar 2023 21:15:04 +0100 Subject: [PATCH 2/6] Removed support for strings in error parser This is to have a SSOT when parsing the errors and remove duality --- .../javascripts/lib/utils/error_message.js | 14 +++++++-- .../security_configuration/components/app.vue | 8 ++--- .../components/manage_via_mr.vue | 24 ++++++++++----- spec/frontend/lib/utils/error_message_spec.js | 30 +++++-------------- .../components/app_spec.js | 26 ++++------------ .../components/manage_via_mr_spec.js | 19 +++++++----- 6 files changed, 56 insertions(+), 65 deletions(-) diff --git a/app/assets/javascripts/lib/utils/error_message.js b/app/assets/javascripts/lib/utils/error_message.js index 3984883dbf7f56..5aa3bc6f995112 100644 --- a/app/assets/javascripts/lib/utils/error_message.js +++ b/app/assets/javascripts/lib/utils/error_message.js @@ -1,7 +1,17 @@ export const USER_FACING_ERROR_MESSAGE_PREFIX = 'UF:'; -export const parseErrorMessage = (error = '', defaultMessage = '') => { - const messageString = typeof error === 'string' ? error : error.message || ''; +/** + * Utility to parse an error object returned from API. + * Can also be used to parse errors as strings to handle + * events from frontend implementations + * + * @param { Object } error - An error object directly from API response + * @param { string } error.message - The error message, returned from API. + * @param { string } defaultMessage - Default user-facing error message + * @returns { string } - A transformed user-facing error message, or defaultMessage + */ +export const parseErrorMessage = (error = {}, defaultMessage = '') => { + const messageString = error.message || ''; return messageString.startsWith(USER_FACING_ERROR_MESSAGE_PREFIX) ? messageString.replace(USER_FACING_ERROR_MESSAGE_PREFIX, '').trim() : defaultMessage; diff --git a/app/assets/javascripts/security_configuration/components/app.vue b/app/assets/javascripts/security_configuration/components/app.vue index 3f1d66f17e0309..e96f71981e5e20 100644 --- a/app/assets/javascripts/security_configuration/components/app.vue +++ b/app/assets/javascripts/security_configuration/components/app.vue @@ -1,7 +1,6 @@ diff --git a/spec/frontend/lib/utils/error_message_spec.js b/spec/frontend/lib/utils/error_message_spec.js index d1cfa78044fcc1..54c630b8ba0120 100644 --- a/spec/frontend/lib/utils/error_message_spec.js +++ b/spec/frontend/lib/utils/error_message_spec.js @@ -10,20 +10,6 @@ const generateErrorWithMessage = (message) => { }; describe('parseErrorMessage', () => { - it.each` - error | expectedResult - ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${errorMessage} - ${`${errorMessage} ${USER_FACING_ERROR_MESSAGE_PREFIX}`} | ${defaultErrorMessage} - ${errorMessage} | ${defaultErrorMessage} - ${undefined} | ${defaultErrorMessage} - ${''} | ${defaultErrorMessage} - `( - 'properly parses "$error" error string and returns "$expectedResult"', - ({ error, expectedResult }) => { - expect(parseErrorMessage(error, defaultErrorMessage)).toEqual(expectedResult); - }, - ); - it.each` error | expectedResult ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${errorMessage} @@ -40,14 +26,14 @@ describe('parseErrorMessage', () => { ); it.each` - error | defaultMessage | expectedResult - ${undefined} | ${defaultErrorMessage} | ${defaultErrorMessage} - ${''} | ${defaultErrorMessage} | ${defaultErrorMessage} - ${{}} | ${defaultErrorMessage} | ${defaultErrorMessage} - ${errorMessage} | ${undefined} | ${''} - ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${undefined} | ${errorMessage} - ${errorMessage} | ${''} | ${''} - ${`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`} | ${''} | ${errorMessage} + error | defaultMessage | expectedResult + ${undefined} | ${defaultErrorMessage} | ${defaultErrorMessage} + ${''} | ${defaultErrorMessage} | ${defaultErrorMessage} + ${{}} | ${defaultErrorMessage} | ${defaultErrorMessage} + ${generateErrorWithMessage(errorMessage)} | ${undefined} | ${''} + ${generateErrorWithMessage(`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`)} | ${undefined} | ${errorMessage} + ${generateErrorWithMessage(errorMessage)} | ${''} | ${''} + ${generateErrorWithMessage(`${USER_FACING_ERROR_MESSAGE_PREFIX} ${errorMessage}`)} | ${''} | ${errorMessage} `( 'properly handles the edge case of error="$error" and defaultMessage="$defaultMessage"', ({ error, defaultMessage, expectedResult }) => { diff --git a/spec/frontend/security_configuration/components/app_spec.js b/spec/frontend/security_configuration/components/app_spec.js index 0ca350f9ed7cb8..ae5316eb12f73f 100644 --- a/spec/frontend/security_configuration/components/app_spec.js +++ b/spec/frontend/security_configuration/components/app_spec.js @@ -26,8 +26,6 @@ import { REPORT_TYPE_LICENSE_COMPLIANCE, REPORT_TYPE_SAST, } from '~/vue_shared/security_reports/constants'; -import { USER_FACING_ERROR_MESSAGE_PREFIX } from '~/lib/utils/error_message'; -import { manageViaMRErrorMessage } from '../constants'; const upgradePath = '/upgrade'; const autoDevopsHelpPagePath = '/autoDevopsHelpPagePath'; @@ -202,21 +200,20 @@ describe('App component', () => { }); }); - describe('when user facing error occurs', () => { + describe('when error occurs', () => { + const errorMessage = 'There was a manage via MR error'; + it('should show Alert with error Message', async () => { expect(findManageViaMRErrorAlert().exists()).toBe(false); - // Prefixed with USER_FACING_ERROR_MESSAGE_PREFIX as used in lib/gitlab/utils/error_message.rb to indicate a user facing error - findFeatureCards() - .at(1) - .vm.$emit('error', `${USER_FACING_ERROR_MESSAGE_PREFIX} ${manageViaMRErrorMessage}`); + findFeatureCards().at(1).vm.$emit('error', errorMessage); await nextTick(); expect(findManageViaMRErrorAlert().exists()).toBe(true); - expect(findManageViaMRErrorAlert().text()).toEqual(manageViaMRErrorMessage); + expect(findManageViaMRErrorAlert().text()).toBe(errorMessage); }); it('should hide Alert when it is dismissed', async () => { - findFeatureCards().at(1).vm.$emit('error', manageViaMRErrorMessage); + findFeatureCards().at(1).vm.$emit('error', errorMessage); await nextTick(); expect(findManageViaMRErrorAlert().exists()).toBe(true); @@ -226,17 +223,6 @@ describe('App component', () => { expect(findManageViaMRErrorAlert().exists()).toBe(false); }); }); - - describe('when non-user facing error occurs', () => { - it('should show Alert with generic error Message', async () => { - expect(findManageViaMRErrorAlert().exists()).toBe(false); - findFeatureCards().at(1).vm.$emit('error', manageViaMRErrorMessage); - - await nextTick(); - expect(findManageViaMRErrorAlert().exists()).toBe(true); - expect(findManageViaMRErrorAlert().text()).toEqual(i18n.genericErrorText); - }); - }); }); describe('Auto DevOps hint alert', () => { diff --git a/spec/frontend/vue_shared/security_reports/components/manage_via_mr_spec.js b/spec/frontend/vue_shared/security_reports/components/manage_via_mr_spec.js index 6345393951ccec..646b37d334b24c 100644 --- a/spec/frontend/vue_shared/security_reports/components/manage_via_mr_spec.js +++ b/spec/frontend/vue_shared/security_reports/components/manage_via_mr_spec.js @@ -8,7 +8,9 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { humanize } from '~/lib/utils/text_utility'; import { redirectTo } from '~/lib/utils/url_utility'; -import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue'; +import ManageViaMr, { + i18n, +} from '~/vue_shared/security_configuration/components/manage_via_mr.vue'; import { REPORT_TYPE_SAST } from '~/vue_shared/security_reports/constants'; import { buildConfigureSecurityFeatureMockFactory } from './apollo_mocks'; @@ -77,10 +79,11 @@ describe('ManageViaMr component', () => { buildConfigureSecurityFeatureMock({ successPath: '', }); - const errorHandler = async () => - buildConfigureSecurityFeatureMock({ - errors: ['foo'], + const errorHandler = async (message = 'foo') => { + return buildConfigureSecurityFeatureMock({ + errors: [message], }); + }; const pendingHandler = () => new Promise(() => {}); describe('when feature is configured', () => { @@ -147,9 +150,11 @@ describe('ManageViaMr component', () => { }); describe.each` - handler | message - ${noSuccessPathHandler} | ${`${featureName} merge request creation mutation failed`} - ${errorHandler} | ${'foo'} + handler | message + ${noSuccessPathHandler} | ${`${featureName} merge request creation mutation failed`} + ${errorHandler.bind(null, 'UF: message')} | ${'message'} + ${errorHandler.bind(null, 'message')} | ${i18n.genericErrorText} + ${errorHandler} | ${i18n.genericErrorText} `('given an error response', ({ handler, message }) => { beforeEach(() => { const apolloProvider = createMockApolloProvider(mutation, handler); -- GitLab From 04e6f3d6a8ee64a02c0d482e6aaf0ebf2dfa4c84 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Fri, 17 Mar 2023 21:36:09 +0100 Subject: [PATCH 3/6] Updated documentation on the utility's usage --- doc/development/api_styleguide.md | 3 ++- doc/development/fe_guide/style/javascript.md | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/doc/development/api_styleguide.md b/doc/development/api_styleguide.md index 828ef21ba9ac82..f05a226abcba52 100644 --- a/doc/development/api_styleguide.md +++ b/doc/development/api_styleguide.md @@ -338,12 +338,13 @@ Also see [verifying N+1 performance](#verifying-with-tests) in tests. When throwing an error with a message that is meant to be user-facing, you should use the error message utility function contained in `lib/gitlab/utils/error_message.rb`. It adds a prefix to the error message, making it distinguishable from non-user-facing error messages. -Please make sure that the Frontend is aware of the prefix usage and is using the according utils. ```ruby Gitlab::Utils::ErrorMessage.to_user_facing('Example user-facing error-message') ``` +Please make sure that the Frontend is aware of the prefix usage and is using the according utils. See [Error handling](fe_guide/style/javascript.md#error-handling) in JavaScript style guide for more info. + ## Include a changelog entry All client-facing changes **must** include a [changelog entry](changelog.md). diff --git a/doc/development/fe_guide/style/javascript.md b/doc/development/fe_guide/style/javascript.md index b35ffdd8669555..378e9c60dd97d1 100644 --- a/doc/development/fe_guide/style/javascript.md +++ b/doc/development/fe_guide/style/javascript.md @@ -332,19 +332,22 @@ Only export the constants as a collection (array, or object) when there is a nee ## Error handling -When catching a server-side error you should use the error message +When catching a server-side error, you should use the error message utility function contained in `app/assets/javascripts/lib/utils/error_message.js`. -This utility parses the received error message and checks for a prefix that indicates -whether the message is meant to be user-facing or not. The utility returns -an object with the message, and a boolean indicating whether the message is meant to be user-facing or not. Please make sure that the Backend is aware of the utils usage and is adding the prefix -to the error message accordingly. +This utility accepts two parameters: the error object received from the server response and a +default error message. The utility examines the message in the error object for a prefix that +indicates whether the message is meant to be user-facing or not. If the message is intended +to be user-facing, the utility returns it as is. Otherwise, it returns the default error +message provided by frontend implementation. ```javascript import { parseErrorMessage } from '~/lib/utils/error_message'; onError(error) { - const { message, userFacing } = parseErrorMessage(error); - - const errorMessage = userFacing ? message : genericErrorText; + const errorMessage = parseErrorMessage(error, genericErrorText); } ``` + +To benefit from this parsing mechanism, the utility user should ensure that the server-side +code is aware of this utility's usage and prefixes the error messages where appropriate +before sending them back to the user. See [Error handling for API](../../api_styleguide.md#error-handling) for more info. -- GitLab From 8caff7f359bd2894c3031b586c845efd5e39a0ab Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Mon, 20 Mar 2023 15:18:33 +0000 Subject: [PATCH 4/6] Removed the note about accepting strings As per review --- app/assets/javascripts/lib/utils/error_message.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/lib/utils/error_message.js b/app/assets/javascripts/lib/utils/error_message.js index 5aa3bc6f995112..61e1a762330c09 100644 --- a/app/assets/javascripts/lib/utils/error_message.js +++ b/app/assets/javascripts/lib/utils/error_message.js @@ -2,8 +2,7 @@ export const USER_FACING_ERROR_MESSAGE_PREFIX = 'UF:'; /** * Utility to parse an error object returned from API. - * Can also be used to parse errors as strings to handle - * events from frontend implementations + * * * @param { Object } error - An error object directly from API response * @param { string } error.message - The error message, returned from API. -- GitLab From 6564d04ec384fc8c2d3b1ad15e8e3ff7d6f309fa Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Mon, 20 Mar 2023 16:23:27 +0100 Subject: [PATCH 5/6] Updated docs as per review --- doc/development/api_styleguide.md | 2 +- doc/development/fe_guide/style/javascript.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/development/api_styleguide.md b/doc/development/api_styleguide.md index f05a226abcba52..34e043a30d6550 100644 --- a/doc/development/api_styleguide.md +++ b/doc/development/api_styleguide.md @@ -343,7 +343,7 @@ It adds a prefix to the error message, making it distinguishable from non-user-f Gitlab::Utils::ErrorMessage.to_user_facing('Example user-facing error-message') ``` -Please make sure that the Frontend is aware of the prefix usage and is using the according utils. See [Error handling](fe_guide/style/javascript.md#error-handling) in JavaScript style guide for more info. +Please make sure that the Frontend is aware of the prefix usage and is using the according utils. See [Error handling](fe_guide/style/javascript.md#error-handling) in JavaScript style guide for more information. ## Include a changelog entry diff --git a/doc/development/fe_guide/style/javascript.md b/doc/development/fe_guide/style/javascript.md index 378e9c60dd97d1..be5208e9b55def 100644 --- a/doc/development/fe_guide/style/javascript.md +++ b/doc/development/fe_guide/style/javascript.md @@ -338,7 +338,7 @@ This utility accepts two parameters: the error object received from the server r default error message. The utility examines the message in the error object for a prefix that indicates whether the message is meant to be user-facing or not. If the message is intended to be user-facing, the utility returns it as is. Otherwise, it returns the default error -message provided by frontend implementation. +message passed as a parameter. ```javascript import { parseErrorMessage } from '~/lib/utils/error_message'; @@ -350,4 +350,5 @@ onError(error) { To benefit from this parsing mechanism, the utility user should ensure that the server-side code is aware of this utility's usage and prefixes the error messages where appropriate -before sending them back to the user. See [Error handling for API](../../api_styleguide.md#error-handling) for more info. +before sending them back to the user. See +[Error handling for API](../../api_styleguide.md#error-handling) for more information. -- GitLab From 9e7558bbbeb399601d2eb1f667ad6e90468c2056 Mon Sep 17 00:00:00 2001 From: Denys Mishunov Date: Mon, 20 Mar 2023 16:58:32 +0100 Subject: [PATCH 6/6] Added comment about error-prefixing anti-pattern As per review --- .../security_configuration/components/manage_via_mr.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/javascripts/vue_shared/security_configuration/components/manage_via_mr.vue b/app/assets/javascripts/vue_shared/security_configuration/components/manage_via_mr.vue index b157cc919a5ff6..e16d62bfdf7806 100644 --- a/app/assets/javascripts/vue_shared/security_configuration/components/manage_via_mr.vue +++ b/app/assets/javascripts/vue_shared/security_configuration/components/manage_via_mr.vue @@ -66,6 +66,9 @@ export default { throw new Error(errors[0]); } + // Sending USER_FACING_ERROR_MESSAGE_PREFIX prefixed messages should happen only in + // the backend. Hence the code below is an anti-pattern. + // The issue to refactor: https://gitlab.com/gitlab-org/gitlab/-/issues/397714 if (!successPath) { throw new Error( `${USER_FACING_ERROR_MESSAGE_PREFIX} ${sprintf(this.$options.i18n.noSuccessPathError, { -- GitLab