fix(web): implement offline detection (#1065)

* xtreme connected edition

* change fallbackRender to fallbackComponent on ErrorBoundary

* call healthz endpoint when error is 500

* display custom offline message

* fix eslint indentation for switchCase

* Update ErrorPage.tsx

* check against error.cause

---------

Co-authored-by: Fabricio Silva <hi@fabricio.dev>
This commit is contained in:
Kyle Sanderson 2023-09-10 08:39:58 -07:00 committed by GitHub
parent d187daa566
commit a1a16adbab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 25 deletions

View file

@ -20,7 +20,7 @@ interface HttpConfig {
function encodeRFC3986URIComponent(str: string): string {
return encodeURIComponent(str).replace(
/[!'()*]/g,
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
);
}
@ -82,27 +82,27 @@ export async function HttpClient<T = unknown>(
const response = await window.fetch(`${baseUrl()}${endpoint}`, init);
switch (response.status) {
case 204:
case 204:
// 204 contains no data, but indicates success
return Promise.resolve<T>({} as T);
case 401:
return Promise.resolve<T>({} as T);
case 401:
// Remove auth info from localStorage
AuthContext.reset();
AuthContext.reset();
// Show an error toast to notify the user what occurred
return Promise.reject(new Error(`[401] Unauthorized: "${endpoint}"`));
case 404:
return Promise.reject(new Error(`[404] Not found: "${endpoint}"`));
case 500:
const health = await window.fetch(`${baseUrl()}api/healthz/liveness`);
if (!health.ok) {
return Promise.reject(
new Error(`[500] Offline (Internal server error): "${endpoint}"`, { cause: "OFFLINE" })
);
}
break;
default:
break;
// Show an error toast to notify the user what occurred
return Promise.reject(new Error(`[401] Unauthorized: "${endpoint}"`));
case 404:
return Promise.reject(new Error(`[404] Not found: "${endpoint}"`));
case 500:
const health = await window.fetch(`${baseUrl()}api/healthz/liveness`);
if (!health.ok) {
return Promise.reject(
new Error(`[500] Offline (Internal server error): "${endpoint}"`, { cause: "OFFLINE" })
);
}
break;
default:
break;
}
const isJson = response.headers.get("Content-Type")?.includes("application/json");