From 67664365bd9d1807bb5cf2a0e2879f5e66e633fc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Jun 2019 11:47:29 -0600 Subject: [PATCH] Display a red box of anger for config syntax errors Fixes https://github.com/vector-im/riot-web/issues/9519 --- src/i18n/strings/en_EN.json | 4 +++- src/vector/getconfig.js | 42 ++++++++++++++++++++----------------- src/vector/index.js | 23 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 2718b8e476..f09f62095d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1,6 +1,8 @@ { - "Unexpected error preparing the app. See console for details.": "Unexpected error preparing the app. See console for details.", + "Your Riot configuration has invalid JSON in it. Please correct the problem and reload the page. The message from the parser is: %(message)s": "Your Riot configuration has invalid JSON in it. Please correct the problem and reload the page. The message from the parser is: %(message)s", + "Invalid JSON": "Invalid JSON", "Your Riot is misconfigured": "Your Riot is misconfigured", + "Unexpected error preparing the app. See console for details.": "Unexpected error preparing the app. See console for details.", "Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.", "Invalid configuration: no default server specified.": "Invalid configuration: no default server specified.", "Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s", diff --git a/src/vector/getconfig.js b/src/vector/getconfig.js index 8c57986bd8..392b32fe07 100644 --- a/src/vector/getconfig.js +++ b/src/vector/getconfig.js @@ -39,28 +39,32 @@ function getConfig(configJsonFilename) { request( { method: "GET", url: configJsonFilename }, (err, response, body) => { - if (err || response.status < 200 || response.status >= 300) { - // Lack of a config isn't an error, we should - // just use the defaults. - // Also treat a blank config as no config, assuming - // the status code is 0, because we don't get 404s - // from file: URIs so this is the only way we can - // not fail if the file doesn't exist when loading - // from a file:// URI. - if (response) { - if (response.status == 404 || (response.status == 0 && body == '')) { - resolve({}); + try { + if (err || response.status < 200 || response.status >= 300) { + // Lack of a config isn't an error, we should + // just use the defaults. + // Also treat a blank config as no config, assuming + // the status code is 0, because we don't get 404s + // from file: URIs so this is the only way we can + // not fail if the file doesn't exist when loading + // from a file:// URI. + if (response) { + if (response.status == 404 || (response.status == 0 && body == '')) { + resolve({}); + } } + reject({err: err, response: response}); + return; } - reject({err: err, response: response}); - return; - } - // We parse the JSON ourselves rather than use the JSON - // parameter, since this throws a parse error on empty - // which breaks if there's no config.json and we're - // loading from the filesystem (see above). - resolve(JSON.parse(body)); + // We parse the JSON ourselves rather than use the JSON + // parameter, since this throws a parse error on empty + // which breaks if there's no config.json and we're + // loading from the filesystem (see above). + resolve(JSON.parse(body)); + } catch (e) { + reject({err: e}); + } }, ); }); diff --git a/src/vector/index.js b/src/vector/index.js index 9270278898..29399b70a2 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -222,10 +222,17 @@ async function loadApp() { let configJson; let configError; + let configSyntaxError = false; try { configJson = await platform.getConfig(); } catch (e) { configError = e; + + if (e && e.err && e.err instanceof SyntaxError) { + console.error("SyntaxError loading config:", e); + configSyntaxError = true; + configJson = {}; // to prevent errors between here and loading CSS for the error box + } } // XXX: We call this twice, once here and once in MatrixChat as a prop. We call it here to ensure @@ -295,6 +302,22 @@ async function loadApp() { } } + // Now that we've loaded the theme (CSS), display the config syntax error if needed. + if (configSyntaxError) { + const errorMessage = _t( + "Your Riot configuration has invalid JSON in it. Please correct the problem and reload the page. " + + "The message from the parser is: %(message)s", + {message: configError.err.message || _t("Invalid JSON")}, + ); + + const GenericErrorPage = sdk.getComponent("structures.GenericErrorPage"); + window.matrixChat = ReactDOM.render( + , + document.getElementById('matrixchat'), + ); + return; + } + const validBrowser = checkBrowserFeatures([ "displaytable", "flexbox", "es5object", "es5function", "localstorage", "objectfit", "indexeddb", "webworkers",