Files
whale-town/scripts/ErrorHandler.gd
2025-12-05 19:00:14 +08:00

244 lines
6.4 KiB
GDScript

extends Node
## 统一错误处理类
## 提供项目中统一的错误处理和日志记录功能
# 错误级别枚举
enum ErrorLevel {
INFO,
WARNING,
ERROR,
CRITICAL
}
# 错误类别
enum ErrorCategory {
NETWORK,
GAME_LOGIC,
UI,
DATA,
SYSTEM
}
# 错误处理器实例(单例模式)
static var instance: ErrorHandler = null
# 错误日志
var error_log: Array[Dictionary] = []
var max_log_entries: int = 1000
func _init():
"""初始化错误处理器"""
if instance == null:
instance = self
## 获取错误处理器实例
static func get_instance() -> ErrorHandler:
"""获取错误处理器单例实例"""
if instance == null:
instance = ErrorHandler.new()
return instance
## 记录错误
static func log_error(
message: String,
level: ErrorLevel = ErrorLevel.ERROR,
category: ErrorCategory = ErrorCategory.SYSTEM,
details: Dictionary = {}
) -> void:
"""
记录错误信息
@param message: 错误消息
@param level: 错误级别
@param category: 错误类别
@param details: 错误详细信息
"""
var handler = get_instance()
var error_entry = {
"timestamp": Time.get_unix_time_from_system(),
"level": level,
"category": category,
"message": message,
"details": details
}
# 添加到日志
handler.error_log.append(error_entry)
# 限制日志大小
if handler.error_log.size() > handler.max_log_entries:
handler.error_log.pop_front()
# 输出到控制台
_print_error(error_entry)
## 打印错误到控制台
static func _print_error(error_entry: Dictionary) -> void:
"""将错误打印到控制台"""
var level_str = ErrorLevel.keys()[error_entry.level]
var category_str = ErrorCategory.keys()[error_entry.category]
var timestamp_str = preload("res://scripts/Utils.gd").format_timestamp(error_entry.timestamp)
var log_message = "[%s] [%s] [%s] %s" % [
timestamp_str,
level_str,
category_str,
error_entry.message
]
# 根据错误级别选择输出方式
match error_entry.level:
ErrorLevel.INFO:
print(log_message)
ErrorLevel.WARNING:
print_rich("[color=yellow]%s[/color]" % log_message)
ErrorLevel.ERROR:
print_rich("[color=red]%s[/color]" % log_message)
ErrorLevel.CRITICAL:
print_rich("[color=purple]%s[/color]" % log_message)
push_error(error_entry.message)
## 记录网络错误
static func log_network_error(message: String, details: Dictionary = {}) -> void:
"""记录网络相关错误"""
log_error(message, ErrorLevel.ERROR, ErrorCategory.NETWORK, details)
## 记录网络警告
static func log_network_warning(message: String, details: Dictionary = {}) -> void:
"""记录网络相关警告"""
log_error(message, ErrorLevel.WARNING, ErrorCategory.NETWORK, details)
## 记录游戏逻辑错误
static func log_game_error(message: String, details: Dictionary = {}) -> void:
"""记录游戏逻辑错误"""
log_error(message, ErrorLevel.ERROR, ErrorCategory.GAME_LOGIC, details)
## 记录UI错误
static func log_ui_error(message: String, details: Dictionary = {}) -> void:
"""记录UI相关错误"""
log_error(message, ErrorLevel.ERROR, ErrorCategory.UI, details)
## 记录数据错误
static func log_data_error(message: String, details: Dictionary = {}) -> void:
"""记录数据相关错误"""
log_error(message, ErrorLevel.ERROR, ErrorCategory.DATA, details)
## 记录信息
static func log_info(message: String, category: ErrorCategory = ErrorCategory.SYSTEM, details: Dictionary = {}) -> void:
"""记录信息级别的日志"""
log_error(message, ErrorLevel.INFO, category, details)
## 获取错误日志
static func get_error_log() -> Array[Dictionary]:
"""获取所有错误日志"""
return get_instance().error_log
## 获取特定级别的错误
static func get_errors_by_level(level: ErrorLevel) -> Array[Dictionary]:
"""
获取特定级别的错误
@param level: 错误级别
@return: 错误列表
"""
var handler = get_instance()
var filtered_errors: Array[Dictionary] = []
for error in handler.error_log:
if error.level == level:
filtered_errors.append(error)
return filtered_errors
## 获取特定类别的错误
static func get_errors_by_category(category: ErrorCategory) -> Array[Dictionary]:
"""
获取特定类别的错误
@param category: 错误类别
@return: 错误列表
"""
var handler = get_instance()
var filtered_errors: Array[Dictionary] = []
for error in handler.error_log:
if error.category == category:
filtered_errors.append(error)
return filtered_errors
## 清除错误日志
static func clear_log() -> void:
"""清除所有错误日志"""
get_instance().error_log.clear()
## 导出错误日志
static func export_log_to_file(file_path: String = "user://error_log.json") -> bool:
"""
将错误日志导出到文件
@param file_path: 文件路径
@return: 是否成功
"""
var handler = get_instance()
var file = FileAccess.open(file_path, FileAccess.WRITE)
if file:
var json_string = JSON.stringify(handler.error_log)
file.store_string(json_string)
file.close()
log_info("Error log exported to: " + file_path)
return true
else:
log_error("Failed to export error log to: " + file_path)
return false
## 处理未捕获的错误
static func handle_uncaught_error(error_message: String, stack_trace: Array = []) -> void:
"""
处理未捕获的错误
@param error_message: 错误消息
@param stack_trace: 堆栈跟踪
"""
var details = {
"stack_trace": stack_trace,
"is_uncaught": true
}
log_error("Uncaught error: " + error_message, ErrorLevel.CRITICAL, ErrorCategory.SYSTEM, details)
## 获取错误统计
static func get_error_statistics() -> Dictionary:
"""
获取错误统计信息
@return: 统计信息字典
"""
var handler = get_instance()
var stats = {
"total_errors": handler.error_log.size(),
"by_level": {},
"by_category": {},
"recent_errors": 0 # 最近1小时的错误数
}
# 初始化计数器
for level in ErrorLevel.values():
stats.by_level[ErrorLevel.keys()[level]] = 0
for category in ErrorCategory.values():
stats.by_category[ErrorCategory.keys()[category]] = 0
# 统计错误
var current_time = Time.get_unix_time_from_system()
var one_hour_ago = current_time - 3600 # 1小时前
for error in handler.error_log:
# 按级别统计
var level_key = ErrorLevel.keys()[error.level]
stats.by_level[level_key] += 1
# 按类别统计
var category_key = ErrorCategory.keys()[error.category]
stats.by_category[category_key] += 1
# 最近错误统计
if error.timestamp > one_hour_ago:
stats.recent_errors += 1
return stats