mirror of
https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT.git
synced 2026-04-05 14:46:34 +00:00
feat(core): 增强卸载处理程序的UI反馈和异常日志记录
- 在卸载处理程序中使用UI管理器显示和隐藏加载对话框,提升用户体验。 - 增加异常钩子,确保未捕获的异常能够记录到日志文件中,增强系统的稳定性和可追溯性。
This commit is contained in:
@@ -1,18 +1,50 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
|
import traceback
|
||||||
from PySide6.QtWidgets import QApplication, QMessageBox
|
from PySide6.QtWidgets import QApplication, QMessageBox
|
||||||
from main_window import MainWindow
|
from main_window import MainWindow
|
||||||
from core.managers.privacy_manager import PrivacyManager
|
from core.managers.privacy_manager import PrivacyManager
|
||||||
from utils.logger import setup_logger, cleanup_old_logs
|
from utils.logger import setup_logger, cleanup_old_logs, log_uncaught_exceptions
|
||||||
from config.config import LOG_FILE, APP_NAME, LOG_RETENTION_DAYS
|
from config.config import LOG_FILE, APP_NAME, LOG_RETENTION_DAYS
|
||||||
from utils import load_config
|
from utils import load_config
|
||||||
|
|
||||||
|
def excepthook(exc_type, exc_value, exc_traceback):
|
||||||
|
"""全局异常处理钩子,将未捕获的异常记录到日志并显示错误对话框"""
|
||||||
|
# 记录异常到日志
|
||||||
|
if hasattr(sys, '_excepthook'):
|
||||||
|
sys._excepthook(exc_type, exc_value, exc_traceback)
|
||||||
|
else:
|
||||||
|
log_uncaught_exceptions(exc_type, exc_value, exc_traceback)
|
||||||
|
|
||||||
|
# 将异常格式化为易读的形式
|
||||||
|
exception_text = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
|
||||||
|
|
||||||
|
# 创建错误对话框
|
||||||
|
msg = f"程序遇到未处理的异常:\n\n{str(exc_value)}\n\n详细错误已记录到日志文件。"
|
||||||
|
try:
|
||||||
|
# 尝试使用QMessageBox显示错误
|
||||||
|
app = QApplication.instance()
|
||||||
|
if app:
|
||||||
|
QMessageBox.critical(None, f"错误 - {APP_NAME}", msg)
|
||||||
|
except Exception:
|
||||||
|
# 如果QMessageBox失败,则使用标准输出
|
||||||
|
print(f"严重错误: {msg}")
|
||||||
|
print(f"详细错误: {exception_text}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 设置主日志
|
# 设置主日志
|
||||||
logger = setup_logger("main")
|
logger = setup_logger("main")
|
||||||
logger.info("应用启动")
|
logger.info("应用启动")
|
||||||
|
|
||||||
|
# 设置全局异常处理钩子
|
||||||
|
sys._excepthook = sys.excepthook
|
||||||
|
sys.excepthook = excepthook
|
||||||
|
|
||||||
|
# 记录程序启动信息
|
||||||
|
logger.info(f"Python版本: {sys.version}")
|
||||||
|
logger.info(f"运行平台: {sys.platform}")
|
||||||
|
|
||||||
# 检查配置中是否启用了调试模式
|
# 检查配置中是否启用了调试模式
|
||||||
config = load_config()
|
config = load_config()
|
||||||
debug_mode = config.get("debug_mode", False)
|
debug_mode = config.get("debug_mode", False)
|
||||||
@@ -48,6 +80,7 @@ if __name__ == "__main__":
|
|||||||
privacy_manager = PrivacyManager()
|
privacy_manager = PrivacyManager()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"初始化隐私协议管理器失败: {e}")
|
logger.error(f"初始化隐私协议管理器失败: {e}")
|
||||||
|
logger.error(f"错误详情: {traceback.format_exc()}")
|
||||||
QMessageBox.critical(
|
QMessageBox.critical(
|
||||||
None,
|
None,
|
||||||
"隐私协议加载错误",
|
"隐私协议加载错误",
|
||||||
|
|||||||
@@ -75,7 +75,11 @@ class UninstallHandler(QObject):
|
|||||||
if debug_mode:
|
if debug_mode:
|
||||||
logger.debug(f"DEBUG: 卸载功能 - 用户选择了目录: {selected_folder}")
|
logger.debug(f"DEBUG: 卸载功能 - 用户选择了目录: {selected_folder}")
|
||||||
|
|
||||||
self.main_window.show_loading_dialog("正在识别游戏目录...")
|
# 使用UI管理器显示加载对话框
|
||||||
|
if hasattr(self.main_window, 'ui_manager'):
|
||||||
|
self.main_window.ui_manager.show_loading_dialog("正在识别游戏目录...")
|
||||||
|
else:
|
||||||
|
logger.warning("无法访问UI管理器,无法显示加载对话框")
|
||||||
|
|
||||||
self.uninstall_thread = UninstallThread(self, selected_folder)
|
self.uninstall_thread = UninstallThread(self, selected_folder)
|
||||||
self.uninstall_thread.finished.connect(self.on_game_detection_finished)
|
self.uninstall_thread.finished.connect(self.on_game_detection_finished)
|
||||||
@@ -83,7 +87,11 @@ class UninstallHandler(QObject):
|
|||||||
|
|
||||||
def on_game_detection_finished(self, game_dirs):
|
def on_game_detection_finished(self, game_dirs):
|
||||||
"""游戏识别完成后的回调"""
|
"""游戏识别完成后的回调"""
|
||||||
self.main_window.hide_loading_dialog()
|
# 使用UI管理器隐藏加载对话框
|
||||||
|
if hasattr(self.main_window, 'ui_manager'):
|
||||||
|
self.main_window.ui_manager.hide_loading_dialog()
|
||||||
|
else:
|
||||||
|
logger.warning("无法访问UI管理器,无法隐藏加载对话框")
|
||||||
|
|
||||||
if not game_dirs:
|
if not game_dirs:
|
||||||
QMessageBox.information(
|
QMessageBox.information(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import datetime
|
|||||||
import sys
|
import sys
|
||||||
import glob
|
import glob
|
||||||
import time
|
import time
|
||||||
|
import traceback
|
||||||
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
|
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
|
||||||
from config.config import LOG_DIR, LOG_FILE, LOG_LEVEL, LOG_MAX_SIZE, LOG_BACKUP_COUNT, LOG_RETENTION_DAYS
|
from config.config import LOG_DIR, LOG_FILE, LOG_LEVEL, LOG_MAX_SIZE, LOG_BACKUP_COUNT, LOG_RETENTION_DAYS
|
||||||
|
|
||||||
@@ -68,6 +69,30 @@ class Logger:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# 增加异常钩子,确保未捕获的异常也会记录到日志文件中
|
||||||
|
def log_uncaught_exceptions(exc_type, exc_value, exc_traceback):
|
||||||
|
"""处理未捕获的异常,记录到日志中"""
|
||||||
|
if issubclass(exc_type, KeyboardInterrupt):
|
||||||
|
# 对于键盘中断,使用默认处理
|
||||||
|
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 获取主日志记录器
|
||||||
|
logger = logging.getLogger('main')
|
||||||
|
|
||||||
|
# 格式化异常信息
|
||||||
|
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
||||||
|
error_message = '未捕获的异常:\n' + ''.join(lines)
|
||||||
|
|
||||||
|
# 记录到日志中
|
||||||
|
logger.critical(error_message)
|
||||||
|
|
||||||
|
# 同时也显示在控制台
|
||||||
|
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
||||||
|
|
||||||
|
# 设置全局异常处理器
|
||||||
|
sys.excepthook = log_uncaught_exceptions
|
||||||
|
|
||||||
def cleanup_old_logs(retention_days=7):
|
def cleanup_old_logs(retention_days=7):
|
||||||
"""清理超过指定天数的旧日志文件
|
"""清理超过指定天数的旧日志文件
|
||||||
|
|
||||||
@@ -147,6 +172,7 @@ def setup_logger(name):
|
|||||||
# 创建更详细的格式器,包括模块名、文件名和行号
|
# 创建更详细的格式器,包括模块名、文件名和行号
|
||||||
formatter = URLCensorFormatter('%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s')
|
formatter = URLCensorFormatter('%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s')
|
||||||
|
|
||||||
|
# 设置处理器的格式化器
|
||||||
console_handler.setFormatter(formatter)
|
console_handler.setFormatter(formatter)
|
||||||
if main_file_handler:
|
if main_file_handler:
|
||||||
main_file_handler.setFormatter(formatter)
|
main_file_handler.setFormatter(formatter)
|
||||||
@@ -156,4 +182,7 @@ def setup_logger(name):
|
|||||||
if main_file_handler:
|
if main_file_handler:
|
||||||
logger.addHandler(main_file_handler)
|
logger.addHandler(main_file_handler)
|
||||||
|
|
||||||
|
# 确保异常可以被正确记录
|
||||||
|
logger.propagate = True
|
||||||
|
|
||||||
return logger
|
return logger
|
||||||
Reference in New Issue
Block a user