From be4d54a6b59029ed2f057a32bea68b79b4d1be69 Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Tue, 9 Jun 2026 20:45:21 +0200 Subject: [PATCH] Feature: "Letzte Fehler anzeigen" im Hilfe-Menue (Error-Ring ins UI) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der Error-Ring aus v1.7.185 war bisher nur ueber die Debug-Server-URL mit Token erreichbar — per RDP ist ein Menueklick drastisch schneller als curl. Neuer Menuepunkt im Hilfe-Dropdown zeigt die letzten 200 WARN/ERROR-Eintraege (Kopf: "X Fehler, Y Warnungen") im bestehenden Bestaetigungs-Dialog mit aufklappbaren Details; der Bestaetigen-Knopf kopiert die komplette Liste in die Zwischenablage — direkt verwertbar fuer Bug-Reports. IPC-Kette nach dem GET_DEBUG_SETUP_CHECK-Muster (ipc.ts, main.ts mit direktem error-ring-Import wie debug-server/support-bundle, preload, preload-api). Read-only auf den In-Memory-Snapshot, kein neues CSS. --- src/main/main.ts | 3 +++ src/preload/preload.ts | 1 + src/renderer/App.tsx | 29 +++++++++++++++++++++++++++++ src/shared/ipc.ts | 1 + src/shared/preload-api.ts | 1 + 5 files changed, 35 insertions(+) diff --git a/src/main/main.ts b/src/main/main.ts index c524de9..bb71dc2 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -5,6 +5,7 @@ import { AddLinksPayload, AppSettings, DebridProvider, UpdateInstallProgress } f import { AppController } from "./app-controller"; import { IPC_CHANNELS } from "../shared/ipc"; import { getLogFilePath, logger } from "./logger"; +import { getRecentErrors } from "./error-ring"; import { APP_NAME } from "./constants"; import { extractHttpLinksFromText } from "./utils"; import { cleanupStaleSubstDrives, shutdownDaemon } from "./extractor"; @@ -626,6 +627,8 @@ function registerIpcHandlers(): void { ipcMain.handle(IPC_CHANNELS.GET_DEBUG_SETUP_CHECK, async () => controller.getDebugSetupCheck()); + ipcMain.handle(IPC_CHANNELS.GET_RECENT_ERRORS, async () => getRecentErrors()); + ipcMain.handle(IPC_CHANNELS.GET_TRACE_CONFIG, async () => controller.getTraceConfig()); ipcMain.handle(IPC_CHANNELS.SET_TRACE_ENABLED, async (_event: IpcMainInvokeEvent, enabled: boolean, note?: string, durationMinutes?: number) => { diff --git a/src/preload/preload.ts b/src/preload/preload.ts index 83d2302..caf1483 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -69,6 +69,7 @@ const api: ElectronApi = { openPackageLog: (packageId: string): Promise => ipcRenderer.invoke(IPC_CHANNELS.OPEN_PACKAGE_LOG, packageId), openItemLog: (itemId: string): Promise => ipcRenderer.invoke(IPC_CHANNELS.OPEN_ITEM_LOG, itemId), getDebugSetupCheck: () => ipcRenderer.invoke(IPC_CHANNELS.GET_DEBUG_SETUP_CHECK), + getRecentErrors: () => ipcRenderer.invoke(IPC_CHANNELS.GET_RECENT_ERRORS), getTraceConfig: () => ipcRenderer.invoke(IPC_CHANNELS.GET_TRACE_CONFIG), setTraceEnabled: (enabled: boolean, note?: string, durationMinutes?: number) => ipcRenderer.invoke(IPC_CHANNELS.SET_TRACE_ENABLED, enabled, note, durationMinutes), rotateDebugToken: (): Promise<{ path: string }> => ipcRenderer.invoke(IPC_CHANNELS.ROTATE_DEBUG_TOKEN), diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 45e5082..c38b5f5 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -3932,6 +3932,32 @@ export function App(): ReactElement { } }; + const onShowRecentErrors = async (): Promise => { + closeMenus(); + try { + const entries = await window.rd.getRecentErrors(); + const errorCount = entries.filter((e) => e.level === "ERROR").length; + const warnCount = entries.filter((e) => e.level === "WARN").length; + const details = entries.map((e) => `${e.ts} [${e.level}] ${e.message}`).join("\n"); + const copy = await askConfirmPrompt({ + title: "Letzte Fehler", + message: entries.length === 0 + ? "Keine Fehler oder Warnungen seit dem App-Start aufgezeichnet." + : `${errorCount} Fehler, ${warnCount} Warnungen (letzte ${entries.length})`, + confirmLabel: entries.length > 0 ? "In Zwischenablage kopieren" : "Schließen", + cancelLabel: "Schließen", + details: details || undefined, + detailsLabel: "Einträge anzeigen" + }); + if (copy && entries.length > 0) { + await navigator.clipboard.writeText(details); + showToast("Fehlerliste kopiert", 2600); + } + } catch (error) { + showToast(`Fehler-Ansicht fehlgeschlagen: ${String(error)}`, 3000); + } + }; + const onRotateDebugToken = async (): Promise => { closeMenus(); const confirmed = await askConfirmPrompt({ @@ -4339,6 +4365,9 @@ export function App(): ReactElement { + diff --git a/src/shared/ipc.ts b/src/shared/ipc.ts index 7284e73..70a401a 100644 --- a/src/shared/ipc.ts +++ b/src/shared/ipc.ts @@ -47,6 +47,7 @@ export const IPC_CHANNELS = { OPEN_PACKAGE_LOG: "app:open-package-log", OPEN_ITEM_LOG: "app:open-item-log", GET_DEBUG_SETUP_CHECK: "app:get-debug-setup-check", + GET_RECENT_ERRORS: "app:get-recent-errors", GET_TRACE_CONFIG: "app:get-trace-config", SET_TRACE_ENABLED: "app:set-trace-enabled", ROTATE_DEBUG_TOKEN: "app:rotate-debug-token", diff --git a/src/shared/preload-api.ts b/src/shared/preload-api.ts index e5d11fa..97ca17f 100644 --- a/src/shared/preload-api.ts +++ b/src/shared/preload-api.ts @@ -66,6 +66,7 @@ export interface ElectronApi { openPackageLog: (packageId: string) => Promise; openItemLog: (itemId: string) => Promise; getDebugSetupCheck: () => Promise; + getRecentErrors: () => Promise>; getTraceConfig: () => Promise; setTraceEnabled: (enabled: boolean, note?: string, durationMinutes?: number) => Promise; rotateDebugToken: () => Promise<{ path: string }>;