This is an automated email from the ASF dual-hosted git repository.
hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git
The following commit(s) were added to refs/heads/master by this push:
new fc0e950 fix(web): show a readable error when the backend is
unreachable
fc0e950 is described below
commit fc0e950a493fcae54d22cefcd5930bb60bbe2d75
Author: Yang Luo <[email protected]>
AuthorDate: Fri Aug 21 16:27:52 2026 +0800
fix(web): show a readable error when the backend is unreachable
---
web/src/App.tsx | 28 ++++++++++++++++------------
web/src/backend/request.ts | 27 +++++++++++++++++++++++++--
web/src/locales/en/data.json | 1 +
web/src/locales/zh/data.json | 1 +
web/src/pages/AgentConfigsPage.tsx | 2 +-
5 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/web/src/App.tsx b/web/src/App.tsx
index 94268b5..c65cfaf 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -134,19 +134,23 @@ export default function App() {
};
const getAccount = React.useCallback(() => {
- AccountBackend.getAccount().then(res => {
- const user = res.data;
- if (user !== null && user !== undefined) {
- user.hostname = res.data2;
- const language = localStorage.getItem("language");
- if (language && language !== Setting.getLanguage()) {
- Setting.setLanguage(language);
+ AccountBackend.getAccount()
+ .then(res => {
+ const user = res.data;
+ if (user !== null && user !== undefined) {
+ user.hostname = res.data2;
+ const language = localStorage.getItem("language");
+ if (language && language !== Setting.getLanguage()) {
+ Setting.setLanguage(language);
+ }
+ setAccount(user);
+ } else {
+ setAccount(null);
}
- setAccount(user);
- } else {
- setAccount(null);
- }
- });
+ })
+ // An unreachable backend is not a signed-in session: without this the
+ // app waits on account forever behind the full-page spinner.
+ .catch(() => setAccount(null));
}, []);
React.useEffect(() => {
diff --git a/web/src/backend/request.ts b/web/src/backend/request.ts
index c8c150a..e837c57 100644
--- a/web/src/backend/request.ts
+++ b/web/src/backend/request.ts
@@ -12,9 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import i18next from "i18next";
+
import {ServerUrl} from "@/Setting";
import type {ApiResponse} from "@/types";
+/**
+ * The API answers in JSON and nothing else, so a body that will not parse is a
+ * request that never reached the Go server: a proxy error page, or the SPA's
own
+ * index.html served as the fallback for an unhandled /api path.
+ */
+function unreachable(status?: number) {
+ const text = i18next.t("general:Cannot connect to the server, please check
that the backend is running");
+ return new Error(status === undefined ? text : `${text} (HTTP ${status})`);
+}
+
/**
* One place where every call to the Go API is made. `credentials: include`
* carries the beego session cookie, which is what the backend authenticates
@@ -35,8 +47,19 @@ export async function request<T = any, T2 = any>(
options.body = JSON.stringify(body);
}
- const response = await fetch(`${ServerUrl}${path}`, options);
- return (await response.json()) as ApiResponse<T, T2>;
+ let response: Response;
+ try {
+ response = await fetch(`${ServerUrl}${path}`, options);
+ } catch {
+ throw unreachable();
+ }
+
+ const text = await response.text();
+ try {
+ return JSON.parse(text) as ApiResponse<T, T2>;
+ } catch {
+ throw unreachable(response.ok ? undefined : response.status);
+ }
}
/** Builds a query string, dropping the parameters that were left empty. */
diff --git a/web/src/locales/en/data.json b/web/src/locales/en/data.json
index 6169967..6938064 100644
--- a/web/src/locales/en/data.json
+++ b/web/src/locales/en/data.json
@@ -244,6 +244,7 @@
"At Any Time": "At Any Time",
"Back Home": "Back Home",
"Cancel": "Cancel",
+ "Cannot connect to the server, please check that the backend is running":
"Cannot connect to the server, please check that the backend is running",
"Certs": "Certs",
"Client IP": "Client IP",
"Client ip": "Client ip",
diff --git a/web/src/locales/zh/data.json b/web/src/locales/zh/data.json
index c36bca0..2b243d5 100644
--- a/web/src/locales/zh/data.json
+++ b/web/src/locales/zh/data.json
@@ -244,6 +244,7 @@
"At Any Time": "任意时间",
"Back Home": "返回首页",
"Cancel": "取消",
+ "Cannot connect to the server, please check that the backend is running":
"无法连接到服务器,请检查后端是否已启动",
"Certs": "证书",
"Client IP": "客户端 IP",
"Client ip": "客户端IP",
diff --git a/web/src/pages/AgentConfigsPage.tsx
b/web/src/pages/AgentConfigsPage.tsx
index 9b656f1..34e8f03 100644
--- a/web/src/pages/AgentConfigsPage.tsx
+++ b/web/src/pages/AgentConfigsPage.tsx
@@ -307,7 +307,7 @@ export default function AgentConfigsPage({account}:
{account: Account}) {
{error ? <MessageAlert description={error} /> : null}
- {scanned && inventories.length === 0 ? (
+ {scanned && !error && inventories.length === 0 ? (
<EmptyState
icon={Package}
title={i18next.t("agentConfig:No agents found")}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]