summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/lib/apiServer.js60
-rw-r--r--ui/lib/retry.js21
-rw-r--r--ui/lib/session.svelte.js24
3 files changed, 78 insertions, 27 deletions
diff --git a/ui/lib/apiServer.js b/ui/lib/apiServer.js
index 0b51883..7edddc3 100644
--- a/ui/lib/apiServer.js
+++ b/ui/lib/apiServer.js
@@ -1,56 +1,58 @@
import axios from 'axios';
+import * as r from './retry.js';
+
export const apiServer = axios.create({
- baseURL: '/api/',
- validateStatus: () => true
+ baseURL: '/api/'
});
export async function boot() {
- return apiServer.get('/boot');
+ return apiServer.get('/boot').catch(responseError);
}
export async function setup(name, password) {
- return apiServer.post('/setup', { name, password });
+ return await apiServer.post('/setup', { name, password }).catch(responseError);
}
export async function logIn(name, password) {
- return apiServer.post('/auth/login', { name, password });
+ return await apiServer.post('/auth/login', { name, password }).catch(responseError);
}
export async function logOut() {
- return apiServer.post('/auth/logout', {});
+ return await apiServer.post('/auth/logout', {}).catch(responseError);
}
export async function changePassword(password, to) {
- return apiServer.post('/password', { password, to });
+ return await apiServer.post('/password', { password, to }).catch(responseError);
}
export async function createChannel(name) {
- return apiServer.post('/channels', { name });
+ return await apiServer.post('/channels', { name }).catch(responseError);
}
export async function postToChannel(channelId, body) {
- return apiServer.post(`/channels/${channelId}`, { body });
+ return await apiServer.post(`/channels/${channelId}`, { body }).catch(responseError);
}
export async function deleteMessage(messageId) {
- return apiServer.delete(`/messages/${messageId}`, {});
+ return await apiServer.delete(`/messages/${messageId}`, {}).catch(responseError);
}
export async function createInvite() {
- return apiServer.post(`/invite`, {});
+ return await apiServer.post(`/invite`, {}).catch(responseError);
}
export async function getInvite(inviteId) {
- return apiServer.get(`/invite/${inviteId}`);
+ return await apiServer.get(`/invite/${inviteId}`).catch(responseError);
}
export async function acceptInvite(inviteId, name, password) {
- const data = {
- name,
- password
- };
- return apiServer.post(`/invite/${inviteId}`, data);
+ return apiServer
+ .post(`/invite/${inviteId}`, {
+ name,
+ password
+ })
+ .catch(responseError);
}
export function subscribeToEvents(resumePoint) {
@@ -62,3 +64,27 @@ export function subscribeToEvents(resumePoint) {
});
return new EventSource(eventsUrl);
}
+
+export class LoggedOut extends Error {}
+
+export class SetupRequired extends Error {}
+
+export async function retry(op) {
+ return await r.retry(op, isRetryable, r.delay(5000));
+}
+
+function responseError(err) {
+ if (err.response) {
+ switch (err.response.status) {
+ case 401:
+ throw new LoggedOut();
+ case 503:
+ throw new SetupRequired();
+ }
+ }
+ throw err;
+}
+
+function isRetryable(err) {
+ return !!err.request;
+}
diff --git a/ui/lib/retry.js b/ui/lib/retry.js
new file mode 100644
index 0000000..777f1be
--- /dev/null
+++ b/ui/lib/retry.js
@@ -0,0 +1,21 @@
+export async function retry(callback, retryCond, delay) {
+ while (true) {
+ try {
+ return await callback();
+ } catch (err) {
+ if (retryCond(err)) {
+ await delay();
+ } else {
+ throw err;
+ }
+ }
+ }
+}
+
+export function delay(millis) {
+ return async () => await sleep(millis);
+}
+
+function sleep(millis) {
+ return new Promise((resolve) => setTimeout(resolve, millis));
+}
diff --git a/ui/lib/session.svelte.js b/ui/lib/session.svelte.js
index b953d9c..21a391d 100644
--- a/ui/lib/session.svelte.js
+++ b/ui/lib/session.svelte.js
@@ -94,16 +94,20 @@ class Session {
}
async function bootOrNavigate(navigateTo) {
- const response = await api.boot();
- switch (response.status) {
- case 401:
- await navigateTo('/login');
- break;
- case 503:
- await navigateTo('/setup');
- break;
- case 200:
- return response.data;
+ try {
+ const response = await api.retry(async () => await api.boot());
+ return response.data;
+ } catch (err) {
+ switch (true) {
+ case err instanceof api.LoggedOut:
+ await navigateTo('/login');
+ break;
+ case err instanceof api.SetupRequired:
+ await navigateTo('/setup');
+ break;
+ default:
+ throw err;
+ }
}
}