mirror of
https://github.com/koodo-reader/koodo-reader.git
synced 2025-12-23 23:17:55 -05:00
feat: add debug log retrieval feature and improve error handling
- Added a new translation key for "Get debug logs" in Chinese localization. - Implemented a UI element in the settings to trigger debug log retrieval. - Enhanced error handling across various components to display error messages using toast notifications. - Updated the sync settings to inform users about Aliyun Drive's restrictions. - Added a new dependency `electron-log` for improved logging capabilities.
This commit is contained in:
18
main.js
18
main.js
@@ -13,6 +13,7 @@ const {
|
||||
const path = require("path");
|
||||
const isDev = require("electron-is-dev");
|
||||
const Store = require("electron-store");
|
||||
const log = require('electron-log/main');
|
||||
const os = require("os");
|
||||
const store = new Store();
|
||||
const fs = require("fs");
|
||||
@@ -37,6 +38,9 @@ var filePath = null;
|
||||
if (process.platform != "darwin" && process.argv.length >= 2) {
|
||||
filePath = process.argv[1];
|
||||
}
|
||||
log.transports.file.fileName = "debug.log";
|
||||
log.transports.file.maxSize = 1024 * 1024; // 1MB
|
||||
log.initialize();
|
||||
store.set(
|
||||
"appVersion", packageJson.version,
|
||||
);
|
||||
@@ -193,6 +197,10 @@ const createMainWin = () => {
|
||||
? "http://localhost:3000"
|
||||
: `file://${path.join(__dirname, "./build/index.html")}`;
|
||||
mainWin.loadURL(urlLocation);
|
||||
mainWin.webContents.on('console-message', (event, level, message, line, sourceId) => {
|
||||
console.log(`[Renderer Console] Level: ${level}, Message: ${message}, Line: ${line}, Source: ${sourceId}`);
|
||||
// 这里你可以进一步处理消息,例如写入文件或发送到其他地方
|
||||
});
|
||||
|
||||
mainWin.on("close", () => {
|
||||
if (mainWin && !mainWin.isDestroyed()) {
|
||||
@@ -650,6 +658,12 @@ const createMainWin = () => {
|
||||
|
||||
return "pong";
|
||||
})
|
||||
ipcMain.handle("get-debug-logs", async (event, config) => {
|
||||
const { shell } = require("electron");
|
||||
const file = log.transports.file.getFile();
|
||||
shell.showItemInFolder(file.path);
|
||||
return "pong";
|
||||
})
|
||||
|
||||
ipcMain.on("user-data", (event, arg) => {
|
||||
event.returnValue = dirPath;
|
||||
@@ -915,9 +929,7 @@ app.on('second-instance', (event, commandLine) => {
|
||||
const originalConsoleLog = console.log;
|
||||
console.log = function (...args) {
|
||||
originalConsoleLog(...args); // 保留原日志
|
||||
if (mainWin && mainWin.webContents) {
|
||||
mainWin.webContents.send('log-message', args.join(' '));
|
||||
}
|
||||
log.info(args.join(' ')); // 写入日志文件
|
||||
};
|
||||
// Handle MacOS deep linking
|
||||
app.on('open-url', (event, url) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "koodo-reader",
|
||||
"main": "main.js",
|
||||
"version": "2.2.2",
|
||||
"version": "2.2.3",
|
||||
"description": "Koodo Reader is a cross-platform ebook reader",
|
||||
"author": {
|
||||
"name": "App by Troye",
|
||||
@@ -28,6 +28,7 @@
|
||||
"copy-text-to-clipboard": "^2.2.0",
|
||||
"dompurify": "^3.2.4",
|
||||
"electron-is-dev": "^1.1.0",
|
||||
"electron-log": "^5.4.3",
|
||||
"electron-store": "^8.0.1",
|
||||
"fflate": "^0.8.2",
|
||||
"file-saver": "^2.0.5",
|
||||
|
||||
2
src/assets/lib/kookit-extra-browser.min.js
vendored
2
src/assets/lib/kookit-extra-browser.min.js
vendored
File diff suppressed because one or more lines are too long
2
src/assets/lib/kookit.min.js
vendored
2
src/assets/lib/kookit.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -210,6 +210,7 @@
|
||||
"Change": "更改",
|
||||
"We have two server regions(Global and China). To change the server region, you need to log out first. Do you want to log out now?": "我们有两个服务器地区:全球和中国。要更改服务器地区,您需要先退出登录。是否现在退出?",
|
||||
"Tasks failed after multiple retries, please check the network connection": "多次重试后任务失败,请检查网络连接",
|
||||
"Get debug logs": "获取调试日志",
|
||||
"There are some unwanted books, notes, highlights show up in other devices after sync is done. But the data in this device is normal. You can reset the sync record in this device, delete the KoodoReader folder in the data source(Turn off Koodo Sync if necessary), and sync again. This should resolve the issue.": "同步完成后,其他设备上出现了一些不需要的图书、笔记和高亮。但此设备中的数据是正常的。您可以在此设备中重置同步记录,删除数据源中的 KoodoReader 文件夹(如有必要,请关闭 Koodo Sync),然后重新同步。这应该可以解决问题。",
|
||||
"Tasks failed after multiple retries, please check the network connection or reauthorize the data source in the settings": "多次重试后任务失败,请检查网络连接或在设置中重新授权数据源",
|
||||
"This data source already contains a library. If you need to merge local and cloud data, please turn off Koodo Sync and resync.": "此数据源已经存在了一个图书库,如果需要将本地和云端的数据合并。请关闭 Koodo Sync 后重新同步。",
|
||||
|
||||
@@ -192,6 +192,9 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
|
||||
try {
|
||||
await this.handleBook(file, md5);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
@@ -433,6 +436,11 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(
|
||||
`Error reading directory ${dirPath}:`,
|
||||
error
|
||||
@@ -459,6 +467,11 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
|
||||
|
||||
await this.getMd5WithBrowser(file);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(
|
||||
`Error processing file ${filePath}:`,
|
||||
error
|
||||
@@ -565,6 +578,9 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
|
||||
|
||||
await this.getMd5WithBrowser(file);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(
|
||||
`Error processing file ${filePath}:`,
|
||||
error
|
||||
|
||||
@@ -5,6 +5,7 @@ import ImportLocal from "../../components/importLocal";
|
||||
import { HeaderProps, HeaderState } from "./interface";
|
||||
import {
|
||||
ConfigService,
|
||||
KookitConfig,
|
||||
TokenService,
|
||||
} from "../../assets/lib/kookit-extra-browser.min";
|
||||
import UpdateInfo from "../../components/dialogs/updateDialog";
|
||||
@@ -661,6 +662,21 @@ class Header extends React.Component<HeaderProps, HeaderState> {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{KookitConfig.CloudMode !== "production" ? (
|
||||
<div className="header-report-container" style={{ right: "300px" }}>
|
||||
<span
|
||||
style={{
|
||||
color: "red",
|
||||
opacity: 1,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
<Trans>TEST</Trans>
|
||||
<span> </span>
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<ImportLocal
|
||||
{...{
|
||||
handleDrag: this.props.handleDrag,
|
||||
|
||||
@@ -490,6 +490,18 @@ class GeneralSetting extends React.Component<
|
||||
<Trans>Clear</Trans>
|
||||
</span>
|
||||
</div>
|
||||
<div className="setting-dialog-new-title">
|
||||
<Trans>Get debug logs</Trans>
|
||||
<span
|
||||
className="change-location-button"
|
||||
onClick={async () => {
|
||||
const { ipcRenderer } = window.require("electron");
|
||||
ipcRenderer.invoke("get-debug-logs", "ping");
|
||||
}}
|
||||
>
|
||||
<Trans>Locate</Trans>
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -249,6 +249,15 @@ class SyncSetting extends React.Component<SettingInfoProps, SettingInfoState> {
|
||||
case "autoOffline":
|
||||
this.handleSetting(item.propName);
|
||||
if (!this.state.autoOffline) {
|
||||
if (this.props.defaultSyncOption === "adrive") {
|
||||
toast.error(
|
||||
this.props.t(
|
||||
"Due to Aliyun Drive's stringent concurrency restrictions, we have bypassed the synchronization of books and covers. Please manually download the books by clicking on them"
|
||||
),
|
||||
{ id: "autoOffline" }
|
||||
);
|
||||
return;
|
||||
}
|
||||
let downloadTasks = await SyncHelper.syncBook(
|
||||
ConfigService,
|
||||
BookUtil
|
||||
@@ -263,9 +272,11 @@ class SyncSetting extends React.Component<SettingInfoProps, SettingInfoState> {
|
||||
ConfigService.getItem("defaultSyncOption")
|
||||
);
|
||||
clearInterval(timer);
|
||||
|
||||
toast.success(this.props.t("Download completed"), {
|
||||
id: "autoOffline",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
toast.dismiss("syncing");
|
||||
}, 3000);
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
officialDictList,
|
||||
officialTranList,
|
||||
} from "../../constants/settingList";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
export function handleBooks(books: BookModel[]) {
|
||||
return { type: "HANDLE_BOOKS", payload: books };
|
||||
@@ -185,6 +186,9 @@ export function handleFetchPlugins() {
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -299,8 +299,10 @@ export const loadFontData = async () => {
|
||||
value: `"${font.fullName}", "${font.postscriptName}", "${font.family}"`,
|
||||
};
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
export const splitSentences = (text) => {
|
||||
|
||||
@@ -194,6 +194,9 @@ export const zipBook = (zip: any) => {
|
||||
}
|
||||
resolve(true);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
@@ -235,6 +238,9 @@ export const zipConfig = (
|
||||
.file("sync.json", sync);
|
||||
resolve(true);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -36,6 +36,9 @@ class BookUtil {
|
||||
);
|
||||
this.uploadBook(key, format);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -38,8 +38,10 @@ export const changePath = async (newPath: string) => {
|
||||
await fs.copy(oldPath, newPath);
|
||||
fs.emptyDirSync(oldPath);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error(`Error copying folder: ${err}`);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
toast.error(errorMessage);
|
||||
console.error(`Error copying folder: ${error}`);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7035,6 +7035,11 @@ electron-is-dev@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
|
||||
integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==
|
||||
|
||||
electron-log@^5.4.3:
|
||||
version "5.4.3"
|
||||
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.4.3.tgz#02a90baf4256950ca416095db6e5745268584d20"
|
||||
integrity sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ==
|
||||
|
||||
electron-publish@26.0.11:
|
||||
version "26.0.11"
|
||||
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.11.tgz#92c9329a101af2836d9d228c82966eca1eee9a7b"
|
||||
|
||||
Reference in New Issue
Block a user