mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-31 03:51:29 +02:00
add more ui logs and fix sonarqube lint
This commit is contained in:
@@ -50,7 +50,8 @@ export const CopyToClipboard = ({
|
||||
setCopied(true);
|
||||
if (copyTimer.current) clearTimeout(copyTimer.current);
|
||||
copyTimer.current = setTimeout(() => setCopied(false), 500);
|
||||
} catch {
|
||||
} catch (e) {
|
||||
console.warn("copy to clipboard failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export function LanguagePicker() {
|
||||
.then((list) => {
|
||||
if (!cancelled) setLanguages(list);
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch((err: unknown) => console.error("load languages failed", err));
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
|
||||
@@ -163,7 +163,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
||||
if (copyTimer.current) clearTimeout(copyTimer.current);
|
||||
copyTimer.current = setTimeout(() => setCopied(false), 1500);
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch((e: unknown) => console.warn("copy to clipboard failed", e));
|
||||
}
|
||||
onClick?.(e);
|
||||
}}
|
||||
|
||||
@@ -279,7 +279,8 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
||||
setCopied(true);
|
||||
if (copyTimer.current) clearTimeout(copyTimer.current);
|
||||
copyTimer.current = setTimeout(() => setCopied(false), 1500);
|
||||
} catch {
|
||||
} catch (e) {
|
||||
console.warn("copy to clipboard failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ import { startConnection } from "@/lib/connection.ts";
|
||||
const NETBIRD_UPLOAD_URL = "https://upload.debug.netbird.io/upload-url";
|
||||
const TRACE_LOG_FILE_COUNT = 5;
|
||||
const PLAIN_LOG_FILE_COUNT = 1;
|
||||
// Lowercase logrus level name sent to Debug.SetLogLevel (the Go binding
|
||||
// upper-cases before the proto enum lookup). Raising to trace is what drives
|
||||
// the daemon's verbose logging and the GUI's gui-client.log during a bundle.
|
||||
const TRACE_LOG_LEVEL = "trace";
|
||||
const DEFAULT_LOG_LEVEL = "info";
|
||||
|
||||
@@ -51,22 +48,53 @@ const throwIfAborted = (signal: AbortSignal) => {
|
||||
const setLogLevelBestEffort = async (level: string) => {
|
||||
try {
|
||||
await DebugSvc.SetLogLevel({ level });
|
||||
} catch {
|
||||
// empty
|
||||
} catch (e) {
|
||||
console.warn("[DebugBundle] best-effort set log level failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
const stopCaptureBestEffort = async () => {
|
||||
try {
|
||||
await DebugSvc.StopBundleCapture();
|
||||
} catch {
|
||||
// empty
|
||||
} catch (e) {
|
||||
console.warn("[DebugBundle] best-effort stop packet capture failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
type LevelState = { original: string; raised: boolean };
|
||||
type CaptureState = { started: boolean };
|
||||
|
||||
type BundleOptions = {
|
||||
trace: boolean;
|
||||
capture: boolean;
|
||||
capturePackets: boolean;
|
||||
hasWindow: boolean;
|
||||
totalSec: number;
|
||||
uploadUrl: string;
|
||||
anonymize: boolean;
|
||||
systemInfo: boolean;
|
||||
};
|
||||
|
||||
const startCaptureBestEffort = async (totalSec: number, pcap: CaptureState) => {
|
||||
try {
|
||||
// Mirror the CLI's safety margin: window + 30s, server caps at 10m.
|
||||
await DebugSvc.StartBundleCapture(totalSec + 30);
|
||||
pcap.started = true;
|
||||
} catch (e) {
|
||||
console.warn("[DebugBundle] start packet capture failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
const cleanupBestEffort = async (pcap: CaptureState, level: LevelState, restoreLevel: boolean) => {
|
||||
if (pcap.started) {
|
||||
await stopCaptureBestEffort();
|
||||
pcap.started = false;
|
||||
}
|
||||
if (restoreLevel && level.raised) {
|
||||
await setLogLevelBestEffort(level.original);
|
||||
}
|
||||
};
|
||||
|
||||
const raiseToTrace = async (
|
||||
signal: AbortSignal,
|
||||
level: LevelState,
|
||||
@@ -76,8 +104,8 @@ const raiseToTrace = async (
|
||||
try {
|
||||
const cur = await DebugSvc.GetLogLevel();
|
||||
if (cur?.level) level.original = cur.level;
|
||||
} catch {
|
||||
// empty
|
||||
} catch (e) {
|
||||
console.warn("[DebugBundle] read current log level failed", e);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
await DebugSvc.SetLogLevel({ level: TRACE_LOG_LEVEL });
|
||||
@@ -89,8 +117,8 @@ const cycleConnection = async (signal: AbortSignal, setStage: (s: DebugStage) =>
|
||||
setStage({ kind: "reconnecting" });
|
||||
try {
|
||||
await ConnectionSvc.Down();
|
||||
} catch {
|
||||
// empty
|
||||
} catch (e) {
|
||||
console.warn("[DebugBundle] disconnect before capture failed", e);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
await startConnection(undefined, signal);
|
||||
@@ -101,8 +129,8 @@ const restoreLogLevel = async (level: LevelState, setStage: (s: DebugStage) => v
|
||||
try {
|
||||
await DebugSvc.SetLogLevel({ level: level.original });
|
||||
level.raised = false;
|
||||
} catch {
|
||||
// empty
|
||||
} catch (e) {
|
||||
console.warn("[DebugBundle] restore log level failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -117,6 +145,58 @@ const waitCaptureWindow = async (
|
||||
}
|
||||
};
|
||||
|
||||
const runBundleFlow = async (
|
||||
signal: AbortSignal,
|
||||
opts: BundleOptions,
|
||||
level: LevelState,
|
||||
pcap: CaptureState,
|
||||
setStage: (s: DebugStage) => void,
|
||||
setLastBundlePath: (p: string) => void,
|
||||
) => {
|
||||
if (opts.trace) {
|
||||
await raiseToTrace(signal, level, setStage);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
|
||||
if (opts.capture) {
|
||||
await cycleConnection(signal, setStage);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
|
||||
if (opts.hasWindow && opts.capturePackets) {
|
||||
await startCaptureBestEffort(opts.totalSec, pcap);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
|
||||
if (opts.hasWindow) {
|
||||
await waitCaptureWindow(signal, setStage, opts.totalSec);
|
||||
}
|
||||
|
||||
if (pcap.started) {
|
||||
await stopCaptureBestEffort();
|
||||
pcap.started = false;
|
||||
}
|
||||
|
||||
if (level.raised) {
|
||||
await restoreLogLevel(level, setStage);
|
||||
}
|
||||
|
||||
throwIfAborted(signal);
|
||||
setStage({ kind: "bundling" });
|
||||
const logFileCount = opts.trace ? TRACE_LOG_FILE_COUNT : PLAIN_LOG_FILE_COUNT;
|
||||
|
||||
if (opts.uploadUrl) setStage({ kind: "uploading" });
|
||||
const result = await DebugSvc.Bundle({
|
||||
anonymize: opts.anonymize,
|
||||
systemInfo: opts.systemInfo,
|
||||
uploadUrl: opts.uploadUrl,
|
||||
logFileCount,
|
||||
});
|
||||
throwIfAborted(signal);
|
||||
if (result.path) setLastBundlePath(result.path);
|
||||
setStage({ kind: "done", result, uploadAttempted: Boolean(opts.uploadUrl) });
|
||||
};
|
||||
|
||||
const useDebugBundle = () => {
|
||||
const [anonymize, setAnonymize] = useState(false);
|
||||
const [systemInfo, setSystemInfo] = useState(true);
|
||||
@@ -150,74 +230,30 @@ const useDebugBundle = () => {
|
||||
abortRef.current = ctrl;
|
||||
const signal = ctrl.signal;
|
||||
|
||||
const uploadUrl = upload ? NETBIRD_UPLOAD_URL : "";
|
||||
const totalSec = Math.max(1, Math.min(30, traceMinutes)) * 60;
|
||||
const level: LevelState = { original: DEFAULT_LOG_LEVEL, raised: false };
|
||||
const pcap: CaptureState = { started: false };
|
||||
const totalSec = Math.max(1, Math.min(30, traceMinutes)) * 60;
|
||||
const hasWindow = capture && totalSec > 0;
|
||||
const opts: BundleOptions = {
|
||||
trace,
|
||||
capture,
|
||||
capturePackets,
|
||||
hasWindow: capture && totalSec > 0,
|
||||
totalSec,
|
||||
uploadUrl: upload ? NETBIRD_UPLOAD_URL : "",
|
||||
anonymize,
|
||||
systemInfo,
|
||||
};
|
||||
|
||||
try {
|
||||
if (trace) {
|
||||
await raiseToTrace(signal, level, setStage);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
|
||||
if (capture) {
|
||||
await cycleConnection(signal, setStage);
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
|
||||
if (hasWindow && capturePackets) {
|
||||
try {
|
||||
// Mirror the CLI's safety margin: window + 30s, server caps at 10m.
|
||||
await DebugSvc.StartBundleCapture(totalSec + 30);
|
||||
pcap.started = true;
|
||||
} catch {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
throwIfAborted(signal);
|
||||
|
||||
if (hasWindow) {
|
||||
await waitCaptureWindow(signal, setStage, totalSec);
|
||||
}
|
||||
|
||||
if (pcap.started) {
|
||||
await stopCaptureBestEffort();
|
||||
pcap.started = false;
|
||||
}
|
||||
|
||||
if (level.raised) {
|
||||
await restoreLogLevel(level, setStage);
|
||||
}
|
||||
|
||||
throwIfAborted(signal);
|
||||
setStage({ kind: "bundling" });
|
||||
const logFileCount = trace ? TRACE_LOG_FILE_COUNT : PLAIN_LOG_FILE_COUNT;
|
||||
|
||||
if (uploadUrl) setStage({ kind: "uploading" });
|
||||
const result = await DebugSvc.Bundle({
|
||||
anonymize,
|
||||
systemInfo,
|
||||
uploadUrl,
|
||||
logFileCount,
|
||||
});
|
||||
throwIfAborted(signal);
|
||||
if (result.path) setLastBundlePath(result.path);
|
||||
setStage({
|
||||
kind: "done",
|
||||
result,
|
||||
uploadAttempted: Boolean(uploadUrl),
|
||||
});
|
||||
await runBundleFlow(signal, opts, level, pcap, setStage, setLastBundlePath);
|
||||
} catch (e) {
|
||||
if (isAbort(e)) {
|
||||
setStage({ kind: "cancelling" });
|
||||
if (pcap.started) await stopCaptureBestEffort();
|
||||
if (level.raised) await setLogLevelBestEffort(level.original);
|
||||
await cleanupBestEffort(pcap, level, true);
|
||||
setStage({ kind: "idle" });
|
||||
return;
|
||||
}
|
||||
if (pcap.started) await stopCaptureBestEffort();
|
||||
await cleanupBestEffort(pcap, level, false);
|
||||
setStage({ kind: "idle" });
|
||||
await errorDialog({
|
||||
Title: i18next.t("settings.error.debugBundleTitle"),
|
||||
|
||||
@@ -124,7 +124,7 @@ const useSettingsState = () => {
|
||||
|
||||
const save = useCallback(
|
||||
async (profileName: string, next: Config, preSharedKey?: string) => {
|
||||
const preSharedKeyWrite = preSharedKey !== undefined ? { preSharedKey } : {};
|
||||
const preSharedKeyWrite = preSharedKey === undefined ? {} : { preSharedKey };
|
||||
try {
|
||||
await SettingsSvc.SetConfig({
|
||||
...next,
|
||||
@@ -194,9 +194,9 @@ const useSettingsState = () => {
|
||||
|
||||
const merged: Config = { ...loaded.data, ...partial };
|
||||
const next: Config =
|
||||
opts?.preSharedKey !== undefined
|
||||
? { ...merged, preSharedKeySet: opts.preSharedKey !== "" }
|
||||
: merged;
|
||||
opts?.preSharedKey === undefined
|
||||
? merged
|
||||
: { ...merged, preSharedKeySet: opts.preSharedKey !== "" };
|
||||
setLoaded({ profileName: loaded.profileName, data: next });
|
||||
await save(loaded.profileName, next, opts?.preSharedKey);
|
||||
},
|
||||
@@ -235,8 +235,9 @@ export const AutostartSettingsProvider = ({ children }: { children: ReactNode })
|
||||
const enabled = supported ? await Autostart.IsEnabled() : false;
|
||||
if (cancelled) return;
|
||||
setAutostart({ supported, enabled });
|
||||
})().catch(() => {
|
||||
})().catch((err: unknown) => {
|
||||
if (cancelled) return;
|
||||
console.warn("[SettingsContext] load autostart state failed", err);
|
||||
setAutostart({ supported: false, enabled: false });
|
||||
});
|
||||
return () => {
|
||||
|
||||
@@ -43,7 +43,7 @@ export const ViewModeProvider = ({ children }: { children: ReactNode }) => {
|
||||
setMode(saved);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch((err: unknown) => console.warn("[ViewModeContext] load preferences failed", err));
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
@@ -54,10 +54,15 @@ export const ViewModeProvider = ({ children }: { children: ReactNode }) => {
|
||||
if (modeRef.current === mode) return;
|
||||
modeRef.current = mode;
|
||||
(async () => {
|
||||
const size = await Window.Size().catch(() => null);
|
||||
const size = await Window.Size().catch((err: unknown) => {
|
||||
console.warn("[ViewModeContext] read window size failed", err);
|
||||
return null;
|
||||
});
|
||||
const width = VIEW_WIDTH[mode];
|
||||
const height = size?.height ?? 640;
|
||||
await Window.SetSize(width, height).catch(() => {});
|
||||
await Window.SetSize(width, height).catch((err: unknown) =>
|
||||
console.warn("[ViewModeContext] set window size failed", err),
|
||||
);
|
||||
setMode(mode);
|
||||
const pref =
|
||||
mode === "advanced" ? ViewModePref.ViewModeAdvanced : ViewModePref.ViewModeDefault;
|
||||
|
||||
@@ -53,11 +53,14 @@ export async function initI18n(): Promise<void> {
|
||||
firstRun = true;
|
||||
language = detectBrowserLanguage(available) ?? "en";
|
||||
}
|
||||
} catch {
|
||||
} catch (e) {
|
||||
console.warn("read preferences for language failed, defaulting to en", e);
|
||||
}
|
||||
|
||||
if (firstRun) {
|
||||
Preferences.SetLanguage(language as LanguageCode).catch(() => {});
|
||||
Preferences.SetLanguage(language as LanguageCode).catch((err: unknown) =>
|
||||
console.warn("persist detected language failed", err),
|
||||
);
|
||||
}
|
||||
|
||||
await i18next.use(initReactI18next).init({
|
||||
|
||||
@@ -197,7 +197,9 @@ export const MainConnectionStatusSwitch = () => {
|
||||
console.error("emit browser-login cancel failed", err),
|
||||
);
|
||||
}
|
||||
WindowManager.CloseBrowserLogin().catch(() => {});
|
||||
WindowManager.CloseBrowserLogin().catch((err: unknown) =>
|
||||
console.warn("close browser-login window failed", err),
|
||||
);
|
||||
setAction("disconnect");
|
||||
try {
|
||||
await Connection.Down();
|
||||
@@ -356,7 +358,9 @@ const IpRow = ({ value }: { value: string }) => {
|
||||
await navigator.clipboard.writeText(value);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 500);
|
||||
} catch {}
|
||||
} catch (e) {
|
||||
console.warn("copy IP to clipboard failed", e);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -38,18 +38,24 @@ export const MainHeader = () => {
|
||||
|
||||
const openSettings = useCallback(() => {
|
||||
setMenuOpen(false);
|
||||
WindowManager.OpenSettings("").catch(() => {});
|
||||
WindowManager.OpenSettings("").catch((err: unknown) =>
|
||||
console.error("open settings window failed", err),
|
||||
);
|
||||
}, []);
|
||||
|
||||
useKeyboardShortcut(SETTINGS_SHORTCUT, openSettings);
|
||||
|
||||
const openAbout = () => {
|
||||
setMenuOpen(false);
|
||||
WindowManager.OpenSettings("about").catch(() => {});
|
||||
WindowManager.OpenSettings("about").catch((err: unknown) =>
|
||||
console.error("open settings (about) window failed", err),
|
||||
);
|
||||
};
|
||||
|
||||
const openManageProfiles = () => {
|
||||
WindowManager.OpenSettings("profiles").catch(() => {});
|
||||
WindowManager.OpenSettings("profiles").catch((err: unknown) =>
|
||||
console.error("open settings (profiles) window failed", err),
|
||||
);
|
||||
};
|
||||
|
||||
const selectMode = (mode: ViewMode) => {
|
||||
|
||||
Reference in New Issue
Block a user