fix(diag): log the full eventloop-delay payload + harden tray icon load

The v3.3.94 measurement computed the main-process event-loop delay, CPU%, per-hoster connection distribution and transient error counts, but logged only '[INFO ] perf': logInfo(ctx, msg) treats a string first arg as the whole message and discards the second, so the payload was thrown away (confirmed in the user's upload-debug.log). Pass the line as a single argument so the real numbers reach the log.

Also: assets/ was missing from the electron-builder files list, so app_icon.ico was never packaged into the asar — new Tray() threw an unhandled rejection on every startup and left no tray icon. Package the icons and wrap createTray in try/catch with a nativeImage fallback so a missing/invalid icon can never crash tray creation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Administrator 2026-06-21 16:47:48 +02:00
parent 7f7da8a619
commit 54dbba223d
2 changed files with 33 additions and 15 deletions

24
main.js
View File

@ -1,6 +1,6 @@
process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || '64'; process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || '64';
const { monitorEventLoopDelay } = require('perf_hooks'); const { monitorEventLoopDelay } = require('perf_hooks');
const { app, BrowserWindow, ipcMain, dialog, clipboard, nativeTheme, Tray, Menu } = require('electron'); const { app, BrowserWindow, ipcMain, dialog, clipboard, nativeTheme, Tray, Menu, nativeImage } = require('electron');
nativeTheme.themeSource = 'dark'; nativeTheme.themeSource = 'dark';
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
@ -225,7 +225,7 @@ function _maybeLogEventLoopDelay(activeJobs) {
upStr = ` active-by-hoster={${byHoster}} transient-errs=${d.transientErrors || 0} pending=${d.pending || 0}`; upStr = ` active-by-hoster={${byHoster}} transient-errs=${d.transientErrors || 0} pending=${d.pending || 0}`;
} }
} catch {} } catch {}
logInfo('perf', `eventloop-delay active=${activeJobs} mean=${mean}ms p99=${p99}ms max=${max}ms stddev=${stddev}ms threadpool=${process.env.UV_THREADPOOL_SIZE}${cpuStr}${resStr}${upStr}`); logInfo(`eventloop-delay active=${activeJobs} mean=${mean}ms p99=${p99}ms max=${max}ms stddev=${stddev}ms threadpool=${process.env.UV_THREADPOOL_SIZE}${cpuStr}${resStr}${upStr}`);
_eventLoopDelay.reset(); _eventLoopDelay.reset();
} catch {} } catch {}
} }
@ -1220,8 +1220,20 @@ function createWindow() {
} }
function createTray() { function createTray() {
const iconPath = path.join(__dirname, 'assets', 'app_icon.ico'); try {
tray = new Tray(iconPath); const candidates = [
path.join(process.resourcesPath || __dirname, 'assets', 'app_icon.ico'),
path.join(__dirname, 'assets', 'app_icon.ico'),
path.join(__dirname, 'assets', 'icon.png')
];
let icon = null;
for (const p of candidates) {
try {
const img = nativeImage.createFromPath(p);
if (img && !img.isEmpty()) { icon = img; break; }
} catch {}
}
tray = new Tray(icon || nativeImage.createEmpty());
tray.setToolTip('Multi-Hoster-Upload'); tray.setToolTip('Multi-Hoster-Upload');
const contextMenu = Menu.buildFromTemplate([ const contextMenu = Menu.buildFromTemplate([
@ -1234,6 +1246,10 @@ function createTray() {
tray.on('click', () => { tray.on('click', () => {
if (mainWindow) { mainWindow.show(); mainWindow.focus(); } if (mainWindow) { mainWindow.show(); mainWindow.focus(); }
}); });
} catch (err) {
tray = null;
debugLog(`createTray failed (non-fatal): ${err && err.message ? err.message : err}`);
}
} }
function updateTrayTooltip(text) { function updateTrayTooltip(text) {

View File

@ -33,7 +33,9 @@
"main.js", "main.js",
"preload.js", "preload.js",
"lib/**/*", "lib/**/*",
"renderer/**/*" "renderer/**/*",
"assets/app_icon.ico",
"assets/app_icon.png"
], ],
"win": { "win": {
"target": [ "target": [