From c3ecfb04eaf6f527a93ffe60c27a7718b23510f6 Mon Sep 17 00:00:00 2001 From: Adarsh Singh Date: Fri, 16 Oct 2026 16:55:45 +0530 Subject: [PATCH] fix(ui): show concise error on form field validation failure during page load (#26818) * fix(ui): show concise error on form field validation failure during page load * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix(ui): remove stray brace introduced by review suggestion * test(ui): assert concise message when form validation returns HTTP 500 --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/test/js/form-checker.test.js | 26 +++++++++++++++++-- .../main/webapp/scripts/hudson-behavior.js | 16 +++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/test/js/form-checker.test.js b/src/test/js/form-checker.test.js index d1da1300af..38d31c4f86 100644 --- a/src/test/js/form-checker.test.js +++ b/src/test/js/form-checker.test.js @@ -39,8 +39,12 @@ describe("FormChecker.delayedCheck", () => { return new Promise((resolve) => setTimeout(resolve, 0)); } - function respondWith(request, body) { - request.resolve({ text: () => Promise.resolve(body) }); + function respondWith(request, body, status = 200) { + request.resolve({ + ok: status >= 200 && status < 300, + status, + text: () => Promise.resolve(body), + }); return settle(); } @@ -80,6 +84,24 @@ describe("FormChecker.delayedCheck", () => { expect(FormChecker.inProgress).toBe(0); }); + it("shows a concise message instead of the error page when a check fails", async () => { + const target = validationArea(); + + FormChecker.delayedCheck("/check", "post", target); + + await respondWith( + requests[0], + "

Oops!

", + 500, + ); + + expect(target.textContent).toContain( + "An internal error occurred during form field validation (HTTP 500)", + ); + expect(target.textContent).not.toContain("Oops!"); + expect(FormChecker.inProgress).toBe(0); + }); + it("never sends a queued check that was aborted while waiting", async () => { const inFlight = validationArea(); const outdated = validationArea(); diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index a0cbee080a..1da1845baf 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -318,7 +318,10 @@ var FormChecker = { x.text() .then((responseText) => { if (!(next.signal && next.signal.aborted)) { - updateValidationArea(next.target, responseText); + updateValidationArea( + next.target, + formatValidationResponse(x, responseText), + ); layoutUpdateCallback.call(); } }) @@ -681,6 +684,13 @@ function fireEvent(element, event) { //======================================================== // using tag names in CSS selector makes the processing faster +function formatValidationResponse(response, responseText) { + // TODO Add i18n support + return response.ok + ? responseText + : `
An internal error occurred during form field validation (HTTP ${response.status}). Please reload the page and if the problem persists, ask the administrator for help.
`; +} + /** * Updates the validation area for a form element * @param {HTMLElement} validationArea The validation area for a given form element @@ -778,12 +788,10 @@ function registerValidator(e) { FormChecker.sendRequest(this.targetUrl(), { method: method, onComplete: function (response) { - // TODO Add i18n support response.text().then((responseText) => { - const errorMessage = `
An internal error occurred during form field validation (HTTP ${response.status}). Please reload the page and if the problem persists, ask the administrator for help.
`; updateValidationArea( validationArea, - response.status === 200 ? responseText : errorMessage, + formatValidationResponse(response, responseText), ); }); },