Improve logging and error handling in API modules: Refactored common, file, and logger APIs to utilize a new logging utility for better traceability. Enhanced error handling for URL opening and file dialog interactions, ensuring informative logs for success and failure cases. Introduced a utility to mask sensitive data in configuration logs, improving security during application initialization.

This commit is contained in:
刘嘉伟 2025-01-08 11:22:09 +08:00
parent 9510a4cb67
commit 19fde43f8b
5 changed files with 69 additions and 23 deletions

View File

@ -1,16 +1,26 @@
import { app, ipcMain, shell } from "electron";
import log from "electron-log";
import { logError, logInfo, LogModule, logWarn } from "../utils/log";
export const initCommonApi = () => {
// 打开链接
ipcMain.on("common.openUrl", async (event, args) => {
if (args) {
log.info(`打开链接:${args}`);
shell.openExternal(args).then(() => {});
logInfo(LogModule.APP, `Attempting to open URL: ${args}`);
try {
await shell.openExternal(args);
logInfo(LogModule.APP, `Successfully opened URL: ${args}`);
} catch (error) {
logError(
LogModule.APP,
`Failed to open URL: ${args}. Error: ${error.message}`
);
}
} else {
logWarn(LogModule.APP, "No URL provided to open.");
}
});
ipcMain.on("common.relaunch", () => {
logInfo(LogModule.APP, "Application is relaunching.");
app.relaunch();
app.quit();
});

View File

@ -1,13 +1,21 @@
import {dialog, ipcMain} from "electron";
import { logInfo, logError, LogModule } from "../utils/log";
export const initFileApi = () => {
ipcMain.handle("file.selectFile", async (event, args) => {
const result = dialog.showOpenDialogSync({
properties: ['openFile'],
filters: [
{name: 'Text Files', extensions: args},
]
})
return result;
logInfo(LogModule.APP, `Attempting to open file dialog with filters: ${JSON.stringify(args)}`);
try {
const result = dialog.showOpenDialogSync({
properties: ['openFile'],
filters: [
{ name: 'Text Files', extensions: args },
]
});
logInfo(LogModule.APP, `File dialog result: ${JSON.stringify(result)}`);
return result;
} catch (error) {
logError(LogModule.APP, `Error opening file dialog: ${error.message}`);
return null;
}
});
}

View File

@ -1,4 +1,5 @@
import { app, ipcMain, shell } from "electron";
import { logInfo, logError, LogModule } from "../utils/log";
const fs = require("fs");
const path = require("path");
@ -8,35 +9,43 @@ export const initLoggerApi = () => {
const readLogger = (callback: (content: string) => void) => {
fs.readFile(logPath, "utf-8", (error, data) => {
if (!error) {
logInfo(LogModule.LOGGER, "Log file read successfully.");
callback(data);
} else {
logError(LogModule.LOGGER, `Error reading log file: ${error.message}`);
}
});
};
ipcMain.on("logger.getLog", async (event, args) => {
logInfo(LogModule.LOGGER, "Received request to get log.");
readLogger(content => {
event.reply("Logger.getLog.hook", content);
logInfo(LogModule.LOGGER, "Log data sent to client.");
});
});
ipcMain.on("logger.update", (event, args) => {
logInfo(LogModule.LOGGER, "Watching log file for changes.");
fs.watch(logPath, (eventType, filename) => {
if (eventType === "change") {
logInfo(LogModule.LOGGER, "Log file changed, reading new content.");
readLogger(content => {
event.reply("Logger.update.hook", content);
logInfo(LogModule.LOGGER, "Updated log data sent to client.");
});
}
});
});
ipcMain.on("logger.openLog", (event, args) => {
console.log('正在打开日志');
logInfo(LogModule.LOGGER, "Attempting to open log file.");
shell.openPath(logPath).then((errorMessage) => {
if (errorMessage) {
console.error('Failed to open Logger:', errorMessage);
logError(LogModule.LOGGER, `Failed to open Logger: ${errorMessage}`);
event.reply("Logger.openLog.hook", false);
} else {
console.log('Logger opened successfully');
logInfo(LogModule.LOGGER, "Logger opened successfully.");
event.reply("Logger.openLog.hook", true);
}
});

View File

@ -24,6 +24,7 @@ import { getConfig } from "../storage/config";
import { initCommonApi } from "../api/common";
import { initLocalApi } from "../api/local";
import { logError, logInfo, LogModule } from "../utils/log";
import { maskSensitiveData } from "../utils/desensitize";
process.env.DIST_ELECTRON = join(__dirname, "..");
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
@ -151,11 +152,7 @@ export const createTray = (config: FrpConfig) => {
win.show();
});
if (config) {
if (config.systemStartupConnect) {
startFrpWorkerProcess(config);
}
}
logInfo(LogModule.APP, `Tray created successfully.`);
};
app.whenReady().then(() => {
logInfo(
@ -171,15 +168,23 @@ app.whenReady().then(() => {
return;
}
const { serverAddr, serverPort, authToken, ...sensitiveData } = config;
logInfo(LogModule.APP, `Config retrieved: ${JSON.stringify({ ...sensitiveData, serverAddr: '**', serverPort: '**', authToken: '**' })}`);
createWindow(config)
.then(r => {
logInfo(LogModule.APP, `Window created successfully.`);
createTray(config);
logInfo(LogModule.APP, `Tray created successfully.`);
if (config) {
logInfo(
LogModule.APP,
`Config retrieved: ${JSON.stringify(
maskSensitiveData(config, ["serverAddr", "serverPort", "authToken", "user", "metaToken"])
)}`
);
if (config.systemStartupConnect) {
startFrpWorkerProcess(config);
}
}
// Initialize APIs
try {
initGitHubApi();

View File

@ -0,0 +1,14 @@
export const maskSensitiveData = (
obj: Record<string, any>,
keysToMask: string[]
) => {
console.log("obj", obj);
const maskedObj = JSON.parse(JSON.stringify(obj));
console.log("masked", maskedObj);
keysToMask.forEach(key => {
if (maskedObj.hasOwnProperty(key)) {
maskedObj[key] = "***";
}
});
return maskedObj;
};