From 153f625ee3f747146b6c2e01b4ed11541184ed4f Mon Sep 17 00:00:00 2001 From: Artem Kurchenko Date: Mon, 22 Sep 2025 17:12:26 +0400 Subject: [PATCH 1/2] Fix: Add error handling to readThemeMarker function - Add try-catch block to handle potential errors in theme marker reading - Return null on error to prevent exceptions from breaking theme detection --- packages/devextreme/js/ui/themes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/devextreme/js/ui/themes.js b/packages/devextreme/js/ui/themes.js index 5a3409572fd3..0cb9e684bd27 100644 --- a/packages/devextreme/js/ui/themes.js +++ b/packages/devextreme/js/ui/themes.js @@ -50,6 +50,8 @@ function readThemeMarker() { return null; } return result.substr(THEME_MARKER_PREFIX.length); + } catch(e) { + return null; } finally { element.remove(); } From 1ac4896314d3f8bd50c0b2c225b47e99f244683f Mon Sep 17 00:00:00 2001 From: Artem Kurchenko Date: Tue, 23 Sep 2025 12:44:30 +0400 Subject: [PATCH 2/2] add tests --- .../tests/DevExpress.ui/themes.tests.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/devextreme/testing/tests/DevExpress.ui/themes.tests.js b/packages/devextreme/testing/tests/DevExpress.ui/themes.tests.js index 75eb02af9219..f500b6e35dad 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui/themes.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui/themes.tests.js @@ -825,3 +825,39 @@ QUnit.module('initialized method', (hooks) => { }); }); }); + +QUnit.module('readThemeMarker error handling', () => { + test('readThemeMarker returns null when getComputedStyle throws an error', function(assert) { + const done = assert.async(); + const originalGetComputedStyle = window.getComputedStyle; + window.getComputedStyle = function() { throw new Error('getComputedStyle fails'); }; + + try { + themes.resetTheme(); + const value = themes.current(); + assert.strictEqual(value, null, 'current() returns null on getComputedStyle error'); + } finally { + window.getComputedStyle = originalGetComputedStyle; + done(); + } + }); + + test('waitForThemeLoad resolves even if getComputedStyle continuously throws', function(assert) { + const done = assert.async(); + const originalGetComputedStyle = window.getComputedStyle; + window.getComputedStyle = function() { throw new Error('boom'); }; + + const TEST_TIMEOUT = 30; + themes.resetTheme(); + themes.setDefaultTimeout(TEST_TIMEOUT); + + themes.ready(() => { + assert.strictEqual(themes.current(), null, 'theme remains null after timeout with errors'); + window.getComputedStyle = originalGetComputedStyle; + themes.setDefaultTimeout(defaultTimeout); + done(); + }); + + themes.waitForThemeLoad('some.nonexistent.theme'); + }); +});