Skip to content

Commit 4954c73

Browse files
committed
extract config error handling out of app.js
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
1 parent 6a5268f commit 4954c73

File tree

4 files changed

+96
-37
lines changed

4 files changed

+96
-37
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright 2020 New Vector Ltd
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import * as React from "react";
18+
import * as PropTypes from "prop-types";
19+
20+
interface IProps {
21+
title: React.ReactNode;
22+
message: React.ReactNode;
23+
}
24+
25+
const ErrorView: React.FC<IProps> = ({title, message}) => {
26+
return <div className="mx_GenericErrorPage">
27+
<div className="mx_GenericErrorPage_box">
28+
<h1>{ title }</h1>
29+
<p>{ message }</p>
30+
</div>
31+
</div>;
32+
};
33+
34+
ErrorView.propTypes = {
35+
title: PropTypes.object.isRequired, // jsx for title
36+
message: PropTypes.object.isRequired, // jsx to display
37+
};
38+
39+
export default ErrorView;
40+

src/vector/app.js

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ function onTokenLoginCompleted() {
126126
window.location.href = formatted;
127127
}
128128

129-
export async function loadApp(fragParams: {}, acceptBrowser: boolean, configError: Error|void) {
129+
export async function loadApp(fragParams: {}, acceptBrowser: boolean) {
130130
// XXX: the way we pass the path to the worker script from webpack via html in body's dataset is a hack
131131
// but alternatives seem to require changing the interface to passing Workers to js-sdk
132132
const vectorIndexeddbWorkerScript = document.body.dataset.vectorIndexeddbWorkerScript;
@@ -146,36 +146,9 @@ export async function loadApp(fragParams: {}, acceptBrowser: boolean, configErro
146146

147147
const params = parseQs(window.location);
148148

149-
// Now that we've loaded the theme (CSS), display the config syntax error if needed.
150-
if (configError && configError.err && configError.err instanceof SyntaxError) {
151-
const errorMessage = (
152-
<div>
153-
<p>
154-
{_t(
155-
"Your Riot configuration contains invalid JSON. Please correct the problem " +
156-
"and reload the page.",
157-
)}
158-
</p>
159-
<p>
160-
{_t(
161-
"The message from the parser is: %(message)s",
162-
{message: configError.err.message || _t("Invalid JSON")},
163-
)}
164-
</p>
165-
</div>
166-
);
167-
168-
const GenericErrorPage = sdk.getComponent("structures.GenericErrorPage");
169-
return <GenericErrorPage message={errorMessage} title={_t("Your Riot is misconfigured")} />;
170-
}
171-
172149
const urlWithoutQuery = window.location.protocol + '//' + window.location.host + window.location.pathname;
173150
console.log("Vector starting at " + urlWithoutQuery);
174-
if (configError) {
175-
return <div className="error">
176-
Unable to load config file: please refresh the page to try again.
177-
</div>;
178-
} else if (acceptBrowser) {
151+
if (acceptBrowser) {
179152
platform.startUpdater();
180153

181154
try {

src/vector/index.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ async function start() {
9797
loadLanguage,
9898
loadTheme,
9999
loadApp,
100+
showError,
101+
_t,
100102
} = await import(
101103
/* webpackChunkName: "init" */
102104
/* webpackPreload: true */
@@ -130,12 +132,18 @@ async function start() {
130132
// load config requires the platform to be ready
131133
const loadConfigPromise = loadConfig();
132134

133-
let configError;
134135
try {
135136
// await config here
136137
await loadConfigPromise;
137-
} catch (err) {
138-
configError = err;
138+
} catch (error) {
139+
// Now that we've loaded the theme (CSS), display the config syntax error if needed.
140+
if (error.err && error.err instanceof SyntaxError) {
141+
return showError(_t("Your Riot is misconfigured"), [
142+
_t("Your Riot configuration contains invalid JSON. Please correct the problem and reload the page."),
143+
_t("The message from the parser is: %(message)s", { message: error.err.message || _t("Invalid JSON")}),
144+
]);
145+
}
146+
return showError(_t("Unable to load config file: please refresh the page to try again."));
139147
}
140148

141149
// Load language after loading config.json so that settingsDefaults.language can be applied
@@ -150,9 +158,27 @@ async function start() {
150158
await loadThemePromise;
151159
await loadLanguagePromise;
152160

153-
// Finally, load the app. All of the other react-sdk imports are in this file which causes the skinner to
154-
// run on the components.
155-
await loadApp(fragparts.params, acceptBrowser, configError);
161+
if (!acceptBrowser) {
162+
await new Promise(resolve => {
163+
// todo
164+
});
165+
}
166+
167+
// Finally, load the app. All of the other react-sdk imports are in this file which causes the skinner to
168+
// run on the components.
169+
await loadApp(fragparts.params, acceptBrowser);
170+
} catch (err) {
171+
console.trace(err);
172+
// check errors in this order:
173+
// Browser Compatibility (skippable)
174+
// config.json
175+
// runtime errors
176+
const { showError } = await import(
177+
/* webpackChunkName: "init" */
178+
/* webpackPreload: true */
179+
"./init");
180+
await showError(err);
181+
}
156182
}
157183
start().catch(err => {
158184
if (!acceptBrowser) {

src/vector/init.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ limitations under the License.
2121
import olmWasmPath from "olm/olm.wasm";
2222
import Olm from 'olm';
2323
import * as ReactDOM from "react-dom";
24+
import * as React from "react";
2425

2526
import * as languageHandler from "matrix-react-sdk/src/languageHandler";
2627
import SettingsStore from "matrix-react-sdk/src/settings/SettingsStore";
@@ -134,12 +135,31 @@ export async function loadTheme() {
134135
setTheme();
135136
}
136137

137-
export async function loadApp(fragParams: {}, acceptBrowser: boolean, configError: Error|void) {
138+
export async function loadApp(fragParams: {}, acceptBrowser: boolean) {
138139
// load app.js async so that its code is not executed immediately and we can catch any exceptions
139140
const module = await import(
140141
/* webpackChunkName: "riot-web-app" */
141142
/* webpackPreload: true */
142143
"./app");
143-
window.matrixChat = ReactDOM.render(await module.loadApp(fragParams, acceptBrowser, configError),
144+
window.matrixChat = ReactDOM.render(await module.loadApp(fragParams, acceptBrowser),
144145
document.getElementById('matrixchat'));
145146
}
147+
148+
export async function showError(title: string, messages?: string[]) {
149+
const ErrorView = (await import(
150+
/* webpackChunkName: "error-view" */
151+
/* webpackPreload: true */
152+
"../components/structures/ErrorView")).default;
153+
const message = <div>
154+
{messages && messages.map(msg => <p key={msg}>
155+
{languageHandler._t(
156+
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.",
157+
)}
158+
</p>)}
159+
</div>;
160+
161+
window.matrixChat = ReactDOM.render(<ErrorView title={title} message={message} />,
162+
document.getElementById('matrixchat'));
163+
}
164+
165+
export const _t = languageHandler._t;

0 commit comments

Comments
 (0)