mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-04 11:43:57 +08:00
feat(logging): capture frontend errors to disk with structured redaction
Frontend half of the logging overhaul. Capture: - Add a global error boundary plus window error/unhandledrejection handlers that persist renderer errors via tauri-plugin-log (new @tauri-apps/plugin-log dependency + log:default capability), so a white-screen crash leaves a trace. Redaction (two layers over every logged value): - Structured serializer: redact by sensitive property name (arrays and nested values included) and by opaque value shape. - Text layer, the universal final pass: redact URL credentials/query, auth schemes, known secret shapes, and named-key array/object values. The container rule closes prefix+JSON, double-encoded, and POJO-error bypasses regardless of which entrypoint the structured data came from. - Render Errors as redacted message + native stack across V8 and WebKit (macOS/Linux) without depending on a single stack format. - Bound all inputs and drop oversized JSON to keep the UI responsive. i18n: - zh / en / ja / zh-TW for the new log settings and error text.
This commit is contained in:
+25
-14
@@ -14,6 +14,13 @@ import { listen } from "@tauri-apps/api/event";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { message } from "@tauri-apps/plugin-dialog";
|
||||
import { exit } from "@tauri-apps/plugin-process";
|
||||
import { FrontendErrorBoundary } from "./components/FrontendErrorBoundary";
|
||||
import {
|
||||
installGlobalErrorHandlers,
|
||||
reportFrontendError,
|
||||
} from "./lib/frontendLogger";
|
||||
|
||||
installGlobalErrorHandlers();
|
||||
|
||||
// 根据平台添加 body class,便于平台特定样式
|
||||
try {
|
||||
@@ -70,7 +77,7 @@ try {
|
||||
});
|
||||
} catch (e) {
|
||||
// 忽略事件订阅异常(例如在非 Tauri 环境下)
|
||||
console.error("订阅 configLoadError 事件失败", e);
|
||||
reportFrontendError("config_load_error_listener", e);
|
||||
}
|
||||
|
||||
async function bootstrap() {
|
||||
@@ -83,10 +90,12 @@ async function bootstrap() {
|
||||
// 数据库版本过新:渲染应用内「升级应用」恢复界面,不进入正常 App
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider defaultTheme="system" storageKey="cc-switch-theme">
|
||||
<DatabaseUpgrade payload={initError} />
|
||||
<Toaster />
|
||||
</ThemeProvider>
|
||||
<FrontendErrorBoundary>
|
||||
<ThemeProvider defaultTheme="system" storageKey="cc-switch-theme">
|
||||
<DatabaseUpgrade payload={initError} />
|
||||
<Toaster />
|
||||
</ThemeProvider>
|
||||
</FrontendErrorBoundary>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
return;
|
||||
@@ -98,19 +107,21 @@ async function bootstrap() {
|
||||
}
|
||||
} catch (e) {
|
||||
// 忽略拉取错误,继续渲染
|
||||
console.error("拉取初始化错误失败", e);
|
||||
reportFrontendError("get_init_error", e);
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider defaultTheme="system" storageKey="cc-switch-theme">
|
||||
<UpdateProvider>
|
||||
<App />
|
||||
<Toaster />
|
||||
</UpdateProvider>
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
<FrontendErrorBoundary>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ThemeProvider defaultTheme="system" storageKey="cc-switch-theme">
|
||||
<UpdateProvider>
|
||||
<App />
|
||||
<Toaster />
|
||||
</UpdateProvider>
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
</FrontendErrorBoundary>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user