feat: standardize logging across UI components

- Replaced console.log and console.error statements with logger methods from @automaker/utils in various UI components, ensuring consistent log formatting and improved readability.
- Enhanced error handling by utilizing logger methods to provide clearer context for issues encountered during operations.
- Updated multiple views and hooks to integrate the new logging system, improving maintainability and debugging capabilities.

This update significantly enhances the observability of UI components, facilitating easier troubleshooting and monitoring.
This commit is contained in:
Shirone
2026-01-02 17:25:13 +01:00
parent 96a999817f
commit 69f3ba9724
86 changed files with 1079 additions and 677 deletions

View File

@@ -13,6 +13,7 @@ import crypto from 'crypto';
import http, { Server } from 'http';
import net from 'net';
import { app, BrowserWindow, ipcMain, dialog, shell, screen } from 'electron';
import { createLogger } from '@automaker/utils/logger';
import {
findNodeExecutable,
buildEnhancedPath,
@@ -35,6 +36,9 @@ import {
systemPathExists,
} from '@automaker/platform';
const logger = createLogger('Electron');
const serverLogger = createLogger('Server');
// Development environment
const isDev = !app.isPackaged;
const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL;
@@ -45,7 +49,7 @@ if (isDev) {
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('dotenv').config({ path: path.join(__dirname, '../.env') });
} catch (error) {
console.warn('[Electron] dotenv not available:', (error as Error).message);
logger.warn('dotenv not available:', (error as Error).message);
}
}
@@ -144,21 +148,21 @@ function ensureApiKey(): string {
const key = electronUserDataReadFileSync(API_KEY_FILENAME).trim();
if (key) {
apiKey = key;
console.log('[Electron] Loaded existing API key');
logger.info('Loaded existing API key');
return apiKey;
}
}
} catch (error) {
console.warn('[Electron] Error reading API key:', error);
logger.warn('Error reading API key:', error);
}
// Generate new key
apiKey = crypto.randomUUID();
try {
electronUserDataWriteFileSync(API_KEY_FILENAME, apiKey, { encoding: 'utf-8', mode: 0o600 });
console.log('[Electron] Generated new API key');
logger.info('Generated new API key');
} catch (error) {
console.error('[Electron] Failed to save API key:', error);
logger.error('Failed to save API key:', error);
}
return apiKey;
}
@@ -183,11 +187,11 @@ function getIconPath(): string | null {
try {
if (!electronAppExists(iconPath)) {
console.warn(`[Electron] Icon not found at: ${iconPath}`);
logger.warn('Icon not found at:', iconPath);
return null;
}
} catch (error) {
console.warn(`[Electron] Icon check failed: ${iconPath}`, error);
logger.warn('Icon check failed:', iconPath, error);
return null;
}
@@ -219,7 +223,7 @@ function loadWindowBounds(): WindowBounds | null {
}
}
} catch (error) {
console.warn('[Electron] Failed to load window bounds:', (error as Error).message);
logger.warn('Failed to load window bounds:', (error as Error).message);
}
return null;
}
@@ -231,9 +235,9 @@ function loadWindowBounds(): WindowBounds | null {
function saveWindowBounds(bounds: WindowBounds): void {
try {
electronUserDataWriteFileSync(WINDOW_BOUNDS_FILENAME, JSON.stringify(bounds, null, 2));
console.log('[Electron] Window bounds saved');
logger.info('Window bounds saved');
} catch (error) {
console.warn('[Electron] Failed to save window bounds:', (error as Error).message);
logger.warn('Failed to save window bounds:', (error as Error).message);
}
}
@@ -371,7 +375,7 @@ async function startStaticServer(): Promise<void> {
return new Promise((resolve, reject) => {
staticServer!.listen(staticPort, () => {
console.log(`[Electron] Static server running at http://localhost:${staticPort}`);
logger.info('Static server running at http://localhost:' + staticPort);
resolve();
});
staticServer!.on('error', reject);
@@ -386,7 +390,7 @@ async function startServer(): Promise<void> {
// Find Node.js executable (handles desktop launcher scenarios)
const nodeResult = findNodeExecutable({
skipSearch: isDev,
logger: (msg: string) => console.log(`[Electron] ${msg}`),
logger: (msg: string) => logger.info(msg),
});
const command = nodeResult.nodePath;
@@ -470,7 +474,7 @@ async function startServer(): Promise<void> {
// Build enhanced PATH that includes Node.js directory (cross-platform)
const enhancedPath = buildEnhancedPath(command, process.env.PATH || '');
if (enhancedPath !== process.env.PATH) {
console.log(`[Electron] Enhanced PATH with Node directory: ${path.dirname(command)}`);
logger.info('Enhanced PATH with Node directory:', path.dirname(command));
}
const env = {
@@ -488,12 +492,12 @@ async function startServer(): Promise<void> {
}),
};
console.log(`[Electron] Server will use port ${serverPort}`);
logger.info('Server will use port', serverPort);
console.log('[Electron] Starting backend server...');
console.log('[Electron] Server path:', serverPath);
console.log('[Electron] Server root (cwd):', serverRoot);
console.log('[Electron] NODE_PATH:', serverNodeModules);
logger.info('Starting backend server...');
logger.info('Server path:', serverPath);
logger.info('Server root (cwd):', serverRoot);
logger.info('NODE_PATH:', serverNodeModules);
serverProcess = spawn(command, args, {
cwd: serverRoot,
@@ -502,20 +506,20 @@ async function startServer(): Promise<void> {
});
serverProcess.stdout?.on('data', (data) => {
console.log(`[Server] ${data.toString().trim()}`);
serverLogger.info(data.toString().trim());
});
serverProcess.stderr?.on('data', (data) => {
console.error(`[Server Error] ${data.toString().trim()}`);
serverLogger.error(data.toString().trim());
});
serverProcess.on('close', (code) => {
console.log(`[Server] Process exited with code ${code}`);
serverLogger.info('Process exited with code', code);
serverProcess = null;
});
serverProcess.on('error', (err) => {
console.error(`[Server] Failed to start server process:`, err);
serverLogger.error('Failed to start server process:', err);
serverProcess = null;
});
@@ -542,7 +546,7 @@ async function waitForServer(maxAttempts = 30): Promise<void> {
reject(new Error('Timeout'));
});
});
console.log('[Electron] Server is ready');
logger.info('Server is ready');
return;
} catch {
await new Promise((r) => setTimeout(r, 500));
@@ -645,10 +649,10 @@ app.whenReady().then(async () => {
const desiredUserDataPath = path.join(app.getPath('appData'), 'Automaker');
if (app.getPath('userData') !== desiredUserDataPath) {
app.setPath('userData', desiredUserDataPath);
console.log('[Electron] userData path set to:', desiredUserDataPath);
logger.info('userData path set to:', desiredUserDataPath);
}
} catch (error) {
console.warn('[Electron] Failed to set userData path:', (error as Error).message);
logger.warn('Failed to set userData path:', (error as Error).message);
}
// Initialize centralized path helpers for Electron
@@ -664,7 +668,7 @@ app.whenReady().then(async () => {
} else {
setElectronAppPaths(__dirname, process.resourcesPath);
}
console.log('[Electron] Initialized path security helpers');
logger.info('Initialized path security helpers');
// Initialize security settings for path validation
// Set DATA_DIR before initializing so it's available for security checks
@@ -679,7 +683,7 @@ app.whenReady().then(async () => {
try {
app.dock.setIcon(iconPath);
} catch (error) {
console.warn('[Electron] Failed to set dock icon:', (error as Error).message);
logger.warn('Failed to set dock icon:', (error as Error).message);
}
}
}
@@ -691,16 +695,12 @@ app.whenReady().then(async () => {
// Find available ports (prevents conflicts with other apps using same ports)
serverPort = await findAvailablePort(DEFAULT_SERVER_PORT);
if (serverPort !== DEFAULT_SERVER_PORT) {
console.log(
`[Electron] Default server port ${DEFAULT_SERVER_PORT} in use, using port ${serverPort}`
);
logger.info('Default server port', DEFAULT_SERVER_PORT, 'in use, using port', serverPort);
}
staticPort = await findAvailablePort(DEFAULT_STATIC_PORT);
if (staticPort !== DEFAULT_STATIC_PORT) {
console.log(
`[Electron] Default static port ${DEFAULT_STATIC_PORT} in use, using port ${staticPort}`
);
logger.info('Default static port', DEFAULT_STATIC_PORT, 'in use, using port', staticPort);
}
// Start static file server in production
@@ -714,7 +714,7 @@ app.whenReady().then(async () => {
// Create window
createWindow();
} catch (error) {
console.error('[Electron] Failed to start:', error);
logger.error('Failed to start:', error);
const errorMessage = (error as Error).message;
const isNodeError = errorMessage.includes('Node.js');
dialog.showErrorBox(
@@ -740,12 +740,12 @@ app.on('window-all-closed', () => {
// (standard macOS behavior). On other platforms, stop servers and quit.
if (process.platform !== 'darwin') {
if (serverProcess && serverProcess.pid) {
console.log('[Electron] All windows closed, stopping server...');
logger.info('All windows closed, stopping server...');
if (process.platform === 'win32') {
try {
execSync(`taskkill /f /t /pid ${serverProcess.pid}`, { stdio: 'ignore' });
} catch (error) {
console.error('[Electron] Failed to kill server process:', (error as Error).message);
logger.error('Failed to kill server process:', (error as Error).message);
}
} else {
serverProcess.kill('SIGTERM');
@@ -754,7 +754,7 @@ app.on('window-all-closed', () => {
}
if (staticServer) {
console.log('[Electron] Stopping static server...');
logger.info('Stopping static server...');
staticServer.close();
staticServer = null;
}
@@ -765,7 +765,7 @@ app.on('window-all-closed', () => {
app.on('before-quit', () => {
if (serverProcess && serverProcess.pid) {
console.log('[Electron] Stopping server...');
logger.info('Stopping server...');
if (process.platform === 'win32') {
try {
// Windows: use taskkill with /t to kill entire process tree
@@ -773,7 +773,7 @@ app.on('before-quit', () => {
// Using execSync to ensure process is killed before app exits
execSync(`taskkill /f /t /pid ${serverProcess.pid}`, { stdio: 'ignore' });
} catch (error) {
console.error('[Electron] Failed to kill server process:', (error as Error).message);
logger.error('Failed to kill server process:', (error as Error).message);
}
} else {
serverProcess.kill('SIGTERM');
@@ -782,7 +782,7 @@ app.on('before-quit', () => {
}
if (staticServer) {
console.log('[Electron] Stopping static server...');
logger.info('Stopping static server...');
staticServer.close();
staticServer = null;
}
@@ -924,6 +924,6 @@ ipcMain.handle('window:updateMinWidth', (_, _sidebarExpanded: boolean) => {
// Quit the application (used when user denies sandbox risk confirmation)
ipcMain.handle('app:quit', () => {
console.log('[Electron] Quitting application via IPC request');
logger.info('Quitting application via IPC request');
app.quit();
});