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(); } 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'); + }); +});