add error msg to profile context and auto update

This commit is contained in:
Eduard Gert
2026-05-21 09:49:32 +02:00
parent 32df29bbd4
commit df61f22d96
6 changed files with 1500 additions and 1736 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -251,6 +251,8 @@
"update.overlay.error.unknownMessage": "unbekannter Fehler",
"update.overlay.error.targetVersion": "v{version}",
"update.overlay.error.targetFallback": "die neue Version",
"update.error.loadStateTitle": "Laden des Update-Status fehlgeschlagen",
"update.error.triggerTitle": "Update-Start fehlgeschlagen",
"update.page.versionLine": "Client wird aktualisiert auf: {version}.",
"update.page.versionLineGeneric": "Client wird aktualisiert.",

View File

@@ -272,6 +272,8 @@
"update.overlay.error.unknownMessage": "unknown error",
"update.overlay.error.targetVersion": "v{version}",
"update.overlay.error.targetFallback": "the new version",
"update.error.loadStateTitle": "Load Update State Failed",
"update.error.triggerTitle": "Start Update Failed",
"update.page.versionLine": "Updating client to: {version}.",
"update.page.versionLineGeneric": "Updating client.",

View File

@@ -251,6 +251,8 @@
"update.overlay.error.unknownMessage": "ismeretlen hiba",
"update.overlay.error.targetVersion": "v{version}",
"update.overlay.error.targetFallback": "az új verzió",
"update.error.loadStateTitle": "Frissítési állapot betöltése sikertelen",
"update.error.triggerTitle": "Frissítés indítása sikertelen",
"update.page.versionLine": "Kliens frissítése erre: {version}.",
"update.page.versionLineGeneric": "Kliens frissítése.",

View File

@@ -8,9 +8,20 @@ import {
useState,
type ReactNode,
} from "react";
import { Events } from "@wailsio/runtime";
import { Dialogs, Events } from "@wailsio/runtime";
import { Update as UpdateSvc, WindowManager } from "@bindings/services";
import type { State as UpdateState } from "@bindings/updater/models.js";
import i18next from "@/lib/i18n";
import { formatErrorMessage } from "@/lib/errors";
// Daemon-down is already surfaced globally by DaemonUnavailableOverlay and
// (for Trigger) handled by the install window's polling-grace branch; a
// second popup on top of those is pure noise. Every Update RPC routes
// through the shared gRPC conn, so the Unavailable code is the marker.
const isDaemonUnavailable = (e: unknown): boolean => {
const msg = e instanceof Error ? e.message : String(e);
return msg.includes("code = Unavailable");
};
type ClientVersionContextValue = {
updateAvailable: boolean;
@@ -64,8 +75,12 @@ export const ClientVersionProvider = ({ children }: { children: ReactNode }) =>
if (cancelled || !s) return;
setState(s);
})
.catch(() => {
/* daemon unreachable — leave defaults */
.catch((e) => {
if (cancelled || isDaemonUnavailable(e)) return;
void Dialogs.Error({
Title: i18next.t("update.error.loadStateTitle"),
Message: formatErrorMessage(e),
});
});
const off = Events.On(EVENT_UPDATE_STATE, (ev: { data: UpdateState }) => {
if (ev?.data) setState(ev.data);
@@ -117,9 +132,18 @@ export const ClientVersionProvider = ({ children }: { children: ReactNode }) =>
setUpdating(true);
WindowManager.OpenInstallProgress(effective.version || "").catch(console.error);
UpdateSvc.Trigger()
.catch(() => {
.catch(async (e) => {
// The daemon may already be down (force-install branch raced
// us). The install window's polling loop handles it.
// us). The install window's polling loop handles that case.
// Anything else is a real failure — close the install window
// (otherwise it spins forever on a daemon that won't ever
// produce a result) and surface the error.
if (isDaemonUnavailable(e)) return;
WindowManager.CloseInstallProgress().catch(console.error);
await Dialogs.Error({
Title: i18next.t("update.error.triggerTitle"),
Message: formatErrorMessage(e),
});
})
.finally(() => setUpdating(false));
}, [effective.version]);

View File

@@ -14,6 +14,7 @@ import {
} from "@bindings/services";
import type { Profile } from "@bindings/services/models.js";
import i18next from "@/lib/i18n";
import { formatErrorMessage } from "@/lib/errors";
const EVENT_PROFILE_CHANGED = "netbird:profile:changed";
@@ -66,7 +67,7 @@ export const ProfileProvider = ({ children }: { children: ReactNode }) => {
}
await Dialogs.Error({
Title: i18next.t("profile.error.loadTitle"),
Message: msg,
Message: formatErrorMessage(e),
});
} finally {
setLoaded(true);