factor out config error handling

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2020-04-08 20:03:45 +01:00
parent 4954c732ee
commit 2837c41ca4
3 changed files with 40 additions and 32 deletions

View File

@ -17,23 +17,29 @@ limitations under the License.
import * as React from "react"; import * as React from "react";
import * as PropTypes from "prop-types"; import * as PropTypes from "prop-types";
import { _t } from "matrix-react-sdk/src/languageHandler";
interface IProps { interface IProps {
title: React.ReactNode; title: string;
message: React.ReactNode; messages?: string[];
} }
const ErrorView: React.FC<IProps> = ({title, message}) => { const ErrorView: React.FC<IProps> = ({title, messages}) => {
return <div className="mx_GenericErrorPage"> return <div className="mx_GenericErrorPage">
<div className="mx_GenericErrorPage_box"> <div className="mx_GenericErrorPage_box">
<h1>{ title }</h1> <h1>{title}</h1>
<p>{ message }</p> <div>
{messages && messages.map(msg => <p key={msg}>
{ _t(msg) }
</p>)}
</div>
</div> </div>
</div>; </div>;
}; };
ErrorView.propTypes = { ErrorView.propTypes = {
title: PropTypes.object.isRequired, // jsx for title title: PropTypes.string.isRequired,
message: PropTypes.object.isRequired, // jsx to display messages: PropTypes.arrayOf(PropTypes.string.isRequired),
}; };
export default ErrorView; export default ErrorView;

View File

@ -131,6 +131,28 @@ async function start() {
preparePlatform(); preparePlatform();
// load config requires the platform to be ready // load config requires the platform to be ready
const loadConfigPromise = loadConfig(); const loadConfigPromise = loadConfig();
await settled(loadConfigPromise); // wait for it to settle
// keep initialising so that we can show any possible error with as many features (theme, i18n) as possible
// Load language after loading config.json so that settingsDefaults.language can be applied
const loadLanguagePromise = loadLanguage();
// as quickly as we possibly can, set a default theme...
const loadThemePromise = loadTheme();
const loadSkinPromise = loadSkin();
// await things settling so that any errors we have to render have features like i18n running
await settled(loadSkinPromise);
await settled(loadThemePromise);
await settled(loadLanguagePromise);
// ##########################
// error handling begins here
// ##########################
if (!acceptBrowser) {
await new Promise(resolve => {
// todo
});
}
try { try {
// await config here // await config here
@ -146,33 +168,20 @@ async function start() {
return showError(_t("Unable to load config file: please refresh the page to try again.")); return showError(_t("Unable to load config file: please refresh the page to try again."));
} }
// Load language after loading config.json so that settingsDefaults.language can be applied // ##################################
const loadLanguagePromise = loadLanguage(); // app load critical path starts here
// as quickly as we possibly can, set a default theme...
const loadThemePromise = loadTheme();
const loadSkinPromise = loadSkin();
// await things starting successfully // await things starting successfully
// ##################################
await loadOlmPromise; await loadOlmPromise;
await settled(loadSkinPromise); await settled(loadSkinPromise);
await loadThemePromise; await loadThemePromise;
await loadLanguagePromise; await loadLanguagePromise;
if (!acceptBrowser) {
await new Promise(resolve => {
// todo
});
}
// Finally, load the app. All of the other react-sdk imports are in this file which causes the skinner to // Finally, load the app. All of the other react-sdk imports are in this file which causes the skinner to
// run on the components. // run on the components.
await loadApp(fragparts.params, acceptBrowser); await loadApp(fragparts.params, acceptBrowser);
} catch (err) { } catch (err) {
console.trace(err); console.trace(err);
// check errors in this order:
// Browser Compatibility (skippable)
// config.json
// runtime errors
const { showError } = await import( const { showError } = await import(
/* webpackChunkName: "init" */ /* webpackChunkName: "init" */
/* webpackPreload: true */ /* webpackPreload: true */
@ -181,6 +190,7 @@ async function start() {
} }
} }
start().catch(err => { start().catch(err => {
console.error(err);
if (!acceptBrowser) { if (!acceptBrowser) {
alert("Incompatible browser"); alert("Incompatible browser");
} }

View File

@ -150,15 +150,7 @@ export async function showError(title: string, messages?: string[]) {
/* webpackChunkName: "error-view" */ /* webpackChunkName: "error-view" */
/* webpackPreload: true */ /* webpackPreload: true */
"../components/structures/ErrorView")).default; "../components/structures/ErrorView")).default;
const message = <div> window.matrixChat = ReactDOM.render(<ErrorView title={title} messages={messages} />,
{messages && messages.map(msg => <p key={msg}>
{languageHandler._t(
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.",
)}
</p>)}
</div>;
window.matrixChat = ReactDOM.render(<ErrorView title={title} message={message} />,
document.getElementById('matrixchat')); document.getElementById('matrixchat'));
} }