Fail more softly on homeserver liveliness errors
This performs liveliness checks on the auth pages to try and show a friendlier error. Earlier checks in the app startup are expected to not block the app from loading on such failures. See https://github.com/vector-im/riot-web/issues/9828
This commit is contained in:
parent
b412103f21
commit
e2fdeec71a
8 changed files with 257 additions and 33 deletions
|
@ -94,6 +94,13 @@ module.exports = React.createClass({
|
|||
phase: PHASE_LOGIN,
|
||||
// The current login flow, such as password, SSO, etc.
|
||||
currentFlow: "m.login.password",
|
||||
|
||||
// We perform liveliness checks later, but for now suppress the errors.
|
||||
// We also track the server dead errors independently of the regular errors so
|
||||
// that we can render it differently, and override any other error the user may
|
||||
// be seeing.
|
||||
serverIsAlive: true,
|
||||
serverDeadError: "",
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -233,7 +240,7 @@ module.exports = React.createClass({
|
|||
username: username,
|
||||
busy: doWellknownLookup, // unset later by the result of onServerConfigChange
|
||||
errorText: null,
|
||||
canTryLogin: true,
|
||||
canTryLogin: this.state.serverIsAlive,
|
||||
});
|
||||
if (doWellknownLookup) {
|
||||
const serverName = username.split(':').slice(1).join(':');
|
||||
|
@ -247,7 +254,19 @@ module.exports = React.createClass({
|
|||
if (e.translatedMessage) {
|
||||
message = e.translatedMessage;
|
||||
}
|
||||
this.setState({errorText: message, busy: false, canTryLogin: false});
|
||||
|
||||
let errorText = message;
|
||||
let discoveryState = {};
|
||||
if (AutoDiscoveryUtils.isLivelinessError(e)) {
|
||||
errorText = this.state.errorText;
|
||||
discoveryState = this._stateForDiscoveryError(e);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
busy: false,
|
||||
errorText,
|
||||
...discoveryState,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -272,7 +291,7 @@ module.exports = React.createClass({
|
|||
} else {
|
||||
this.setState({
|
||||
errorText: null,
|
||||
canTryLogin: true,
|
||||
canTryLogin: this.state.serverIsAlive,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -297,13 +316,25 @@ module.exports = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
_initLoginLogic: function(hsUrl, isUrl) {
|
||||
const self = this;
|
||||
_stateForDiscoveryError: function(err) {
|
||||
return {
|
||||
canTryLogin: false,
|
||||
...AutoDiscoveryUtils.authComponentStateForError(err),
|
||||
};
|
||||
},
|
||||
|
||||
_initLoginLogic: async function(hsUrl, isUrl) {
|
||||
hsUrl = hsUrl || this.props.serverConfig.hsUrl;
|
||||
isUrl = isUrl || this.props.serverConfig.isUrl;
|
||||
|
||||
// TODO: TravisR - Only use this if the homeserver is the default homeserver
|
||||
const fallbackHsUrl = this.props.fallbackHsUrl;
|
||||
let isDefaultServer = false;
|
||||
if (this.props.serverConfig.isDefault
|
||||
&& hsUrl === this.props.serverConfig.hsUrl
|
||||
&& isUrl === this.props.serverConfig.isUrl) {
|
||||
isDefaultServer = true;
|
||||
}
|
||||
|
||||
const fallbackHsUrl = isDefaultServer ? this.props.fallbackHsUrl : null;
|
||||
|
||||
const loginLogic = new Login(hsUrl, isUrl, fallbackHsUrl, {
|
||||
defaultDeviceDisplayName: this.props.defaultDeviceDisplayName,
|
||||
|
@ -315,6 +346,19 @@ module.exports = React.createClass({
|
|||
loginIncorrect: false,
|
||||
});
|
||||
|
||||
// Do a quick liveliness check on the URLs
|
||||
try {
|
||||
await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(hsUrl, isUrl);
|
||||
this.setState({serverIsAlive: true, errorText: "", canTryLogin: true});
|
||||
} catch (e) {
|
||||
const discoveryState = this._stateForDiscoveryError(e);
|
||||
this.setState({
|
||||
busy: false,
|
||||
...discoveryState,
|
||||
});
|
||||
return; // Server is dead - do not continue.
|
||||
}
|
||||
|
||||
loginLogic.getFlows().then((flows) => {
|
||||
// look for a flow where we understand all of the steps.
|
||||
for (let i = 0; i < flows.length; i++ ) {
|
||||
|
@ -339,14 +383,14 @@ module.exports = React.createClass({
|
|||
"supported by this client.",
|
||||
),
|
||||
});
|
||||
}, function(err) {
|
||||
self.setState({
|
||||
errorText: self._errorTextFromError(err),
|
||||
}, (err) => {
|
||||
this.setState({
|
||||
errorText: this._errorTextFromError(err),
|
||||
loginIncorrect: false,
|
||||
canTryLogin: false,
|
||||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
}).finally(() => {
|
||||
this.setState({
|
||||
busy: false,
|
||||
});
|
||||
}).done();
|
||||
|
@ -485,7 +529,7 @@ module.exports = React.createClass({
|
|||
onForgotPasswordClick={this.props.onForgotPasswordClick}
|
||||
loginIncorrect={this.state.loginIncorrect}
|
||||
serverConfig={this.props.serverConfig}
|
||||
disableSubmit={this.isBusy()}
|
||||
disableSubmit={this.isBusy() || !this.state.serverIsAlive}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
@ -522,6 +566,16 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
let serverDeadSection;
|
||||
if (!this.state.serverIsAlive) {
|
||||
// TODO: TravisR - Design from Nad
|
||||
serverDeadSection = (
|
||||
<div className="mx_Login_error">
|
||||
{this.state.serverDeadError}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthPage>
|
||||
<AuthHeader />
|
||||
|
@ -531,6 +585,7 @@ module.exports = React.createClass({
|
|||
{loader}
|
||||
</h2>
|
||||
{ errorTextSection }
|
||||
{ serverDeadSection }
|
||||
{ this.renderServerComponent() }
|
||||
{ this.renderLoginComponentForStep() }
|
||||
<a className="mx_AuthBody_changeFlow" onClick={this.onRegisterClick} href="#">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue