Skip to content

Commit 9715eca

Browse files
quthlajmattheis
authored andcommitted
Show banner on server errors.
1 parent ed25454 commit 9715eca

File tree

5 files changed

+33
-19
lines changed

5 files changed

+33
-19
lines changed

ui/src/CurrentUser.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ const tokenKey = 'gotify-login-key';
1111
export class CurrentUser {
1212
private tokenCache: string | null = null;
1313
private reconnectTimeoutId: number | null = null;
14-
private readonly reconnectTime: number = 3000;
14+
private reconnectTime = 7500;
1515
@observable
1616
public loggedIn = false;
1717
@observable
1818
public authenticating = false;
1919
@observable
2020
public user: IUser = {name: 'unknown', admin: false, id: -1};
2121
@observable
22-
public hasNetwork = true;
22+
public connectionErrorMessage: string | null = null;
2323

2424
public constructor(private readonly snack: SnackReporter) {}
2525

@@ -87,16 +87,24 @@ export class CurrentUser {
8787
.then((passThrough) => {
8888
this.user = passThrough.data;
8989
this.loggedIn = true;
90-
this.hasNetwork = true;
90+
this.connectionErrorMessage = null;
91+
this.reconnectTime = 7500;
9192
return passThrough;
9293
})
9394
.catch((error: AxiosError) => {
9495
if (!error || !error.response) {
95-
this.lostNetwork();
96+
this.connectionError('No network connection or server unavailable.');
9697
return Promise.reject(error);
9798
}
9899

99-
this.hasNetwork = true;
100+
if (error.response.status >= 500) {
101+
this.connectionError(
102+
`${error.response.statusText} (code: ${error.response.status}).`
103+
);
104+
return Promise.reject(error);
105+
}
106+
107+
this.connectionErrorMessage = null;
100108

101109
if (error.response.status >= 400 && error.response.status < 500) {
102110
this.logout();
@@ -135,14 +143,15 @@ export class CurrentUser {
135143
});
136144
};
137145

138-
private lostNetwork = () => {
139-
this.hasNetwork = false;
146+
private connectionError = (message: string) => {
147+
this.connectionErrorMessage = message;
140148
if (this.reconnectTimeoutId !== null) {
141149
window.clearTimeout(this.reconnectTimeoutId);
142150
}
143151
this.reconnectTimeoutId = window.setTimeout(
144152
() => this.tryReconnect(true),
145153
this.reconnectTime
146154
);
155+
this.reconnectTime = Math.min(this.reconnectTime * 2, 120000);
147156
};
148157
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import React from 'react';
22
import Button from '@material-ui/core/Button';
33
import Typography from '@material-ui/core/Typography';
44

5-
interface NetworkLostBannerProps {
5+
interface ConnectionErrorBannerProps {
66
height: number;
77
retry: () => void;
8+
message: string;
89
}
910

10-
export const NetworkLostBanner = ({height, retry}: NetworkLostBannerProps) => {
11+
export const ConnectionErrorBanner = ({height, retry, message}: ConnectionErrorBannerProps) => {
1112
return (
1213
<div
1314
style={{
@@ -18,7 +19,7 @@ export const NetworkLostBanner = ({height, retry}: NetworkLostBannerProps) => {
1819
position: 'relative',
1920
}}>
2021
<Typography align="center" variant="h6" style={{lineHeight: `${height}px`}}>
21-
No network connection.{' '}
22+
{message}{' '}
2223
<Button variant="outlined" onClick={retry}>
2324
Retry
2425
</Button>

ui/src/layout/Layout.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import Users from '../user/Users';
2020
import {observer} from 'mobx-react';
2121
import {observable} from 'mobx';
2222
import {inject, Stores} from '../inject';
23-
import {NetworkLostBanner} from '../common/NetworkLostBanner';
23+
import {ConnectionErrorBanner} from '../common/ConnectionErrorBanner';
2424
import {IVersion} from '../types';
2525

2626
const styles = (theme: Theme) => ({
@@ -88,8 +88,8 @@ class Layout extends React.Component<
8888
authenticating,
8989
user: {name, admin},
9090
logout,
91-
hasNetwork,
9291
tryReconnect,
92+
connectionErrorMessage,
9393
},
9494
} = this.props;
9595
const theme = themeMap[currentTheme];
@@ -98,13 +98,17 @@ class Layout extends React.Component<
9898
<MuiThemeProvider theme={theme}>
9999
<HashRouter>
100100
<div>
101-
{hasNetwork ? null : (
102-
<NetworkLostBanner height={64} retry={() => tryReconnect()} />
101+
{!connectionErrorMessage ? null : (
102+
<ConnectionErrorBanner
103+
height={64}
104+
retry={() => tryReconnect()}
105+
message={connectionErrorMessage}
106+
/>
103107
)}
104108
<div style={{display: 'flex'}}>
105109
<CssBaseline />
106110
<Header
107-
style={{top: hasNetwork ? 0 : 64}}
111+
style={{top: !connectionErrorMessage ? 0 : 64}}
108112
admin={admin}
109113
name={name}
110114
version={version}

ui/src/reactions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ export const registerReactions = (stores: StoreMapping) => {
3030
);
3131

3232
reaction(
33-
() => stores.currentUser.hasNetwork,
34-
(hasNetwork) => {
35-
if (hasNetwork) {
33+
() => stores.currentUser.connectionErrorMessage,
34+
(connectionErrorMessage) => {
35+
if (!connectionErrorMessage) {
3636
clearAll();
3737
loadAll();
3838
}

ui/src/user/Login.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Login extends Component<Stores<'currentUser'>> {
4444
size="large"
4545
className="login"
4646
color="primary"
47-
disabled={!this.props.currentUser.hasNetwork}
47+
disabled={!!this.props.currentUser.connectionErrorMessage}
4848
style={{marginTop: 15, marginBottom: 5}}
4949
onClick={this.login}>
5050
Login

0 commit comments

Comments
 (0)