last_error
简介
参考 windows 的 last error 设置, 将错误信息保存到 协程的 local_user_value 中, 方便在协程中获取错误信息, 从而将底层的错误信息暴露给上层
Last Error 模块使用说明文档
概述
last_error
模块是一个专为 GameScript 语言设计的错误处理模块,参考了 Windows 的 GetLastError() 机制。该模块将错误信息保存到协程的本地用户值(local_user_value)中,使得底层的错误信息能够方便地暴露给上层调用者。
主要功能
1. 错误处理
- 设置错误信息:支持格式化的错误信息设置
- 获取错误信息:支持获取纯文本错误信息或带堆栈的错误对象
- 一次性获取:错误信息获取后自动清理,避免重复处理
2. 警告处理
- 设置警告信息:支持格式化的警告信息设置
- 获取警告信息:支持获取纯文本警告信息或带堆栈的警告对象
- 独立于错误:警告和错误信息独立存储和处理
3. 堆栈跟踪
- 自动堆栈收集:自动收集调用堆栈信息
- 精确定位:准确定位错误发生的位置
- 调用链追踪:提供完整的函数调用链信息
4. 配置管理
- 输出控制:控制错误和警告是否输出到控制台
- 严格模式:防止错误信息被覆盖而未处理
- 灵活配置:支持运行时动态调整配置
优缺点分析
优点
-
简化错误处理
- 统一的错误处理机制,避免复杂的异常传递
- 类似于 Windows GetLastError() 的熟悉模式
- 支持格式化错误信息,便于调试
-
自动堆栈跟踪
- 自动收集调用堆栈信息
- 精确定位错误发生位置
- 便于调试和问题诊断
-
灵活 配置
- 可控制错误和警告的输出
- 支持严格模式防止错误丢失
- 运行时动态调整配置
-
协程支持
- 基于协程的本地存储, 不需要关心错误的消息的回收问题
- 支持多协程并发执行
- 错误信息隔离,避免相互影响
-
轻量级设计
- 简单易用的 API
- 最小化性能开销
- 不依赖复杂的异常机制
使用场景
1. 文件操作错误处理
bool read_config_file(string filename)
{
// 模拟文件读取
if (!file_exists(filename)) {
last_error.set_error("配置文件不存在: %s", filename);
return false;
}
if (!has_read_permission(filename)) {
last_error.set_error("没有读取权限: %s", filename);
return false;
}
return true;
}
2. 网络连接错误处理
bool connect_to_server(string host, int port)
{
// 模拟网络连接
if (!network_available()) {
last_error.set_error("网络不可用");
return false;
}
if (!can_reach_host(host, port)) {
last_error.set_error("无法连接到服务器 %s:%d", host, port);
return false;
}
return true;
}
3. 数据库操作错误处理
array query_database(string sql)
{
// 模拟数据库查询
if (!database_connected()) {
last_error.set_error("数据库未连接");
return nil;
}
if (!validate_sql(sql)) {
last_error.set_error("SQL 语句格式错误: %s", sql);
return nil;
}
return execute_query(sql);
}
4. 系统服务错误处理
bool start_service(string service_name)
{
// 模拟服务启动
if (!service_exists(service_name)) {
last_error.set_error("服务不存在: %s", service_name);
return false;
}
if (service_running(service_name)) {
last_error.set_warning("服务 %s 已经在运行", service_name);
return true;
}
if (!start_service_internal(service_name)) {
last_error.set_error("启动服务失败: %s", service_name);
return false;
}
return true;
}
5. 游戏逻辑错误处理
bool load_game_level(string level_name)
{
// 模拟游戏关卡加载
if (!level_file_exists(level_name)) {
last_error.set_error("关卡文件不存在: %s", level_name);
return false;
}
if (!validate_level_format(level_name)) {
last_error.set_error("关卡文件格式错误: %s", level_name);
return false;
}
if (!load_level_resources(level_name)) {
last_error.set_error("加载关卡资源失败: %s", level_name);
return false;
}
return true;
}
最佳实践
- 启用严格模式:在开发阶段启用严格模式,确保错误得到及时处理
- 及时处理错误:调用可能失败的函数后,立即检查错误状态
- 记录堆栈信息:对于关键错误,使用
get_error_with_stack()
获取详细信息 - 合理使用警告:对于非致命问题使用警告机制
- 配置输出控制:在生产环境中适当控制错误输出,避免信息泄露
总结
last_error
模块提供了一种简单而有效的错误处理机制,特别适合于 GameScript 语言的协程环境。它通过统一的 API 简化了错误处理流程,提供了堆栈跟踪和灵活的配置选项。虽然在功能上有一些限制,但对于大多数应用场景来说,它提供了足够的错误处理能力。
在使用时,建议结合严格模式和及时的错误检查,以确保错误得到妥善处理。对于复杂的错误处理需求,可以考虑在此基础上扩展更多的功能。
API 说明
错误处理 API
set_error(string msg, ...)
设置错误信息,支持格式化字符串。
参数:
msg
: 错误信息格式字符串...
: 格式字符串的参数
示例:
last_error.set_error("连接失败: 服务器 %s 端口 %d 不可达", "192.168.1.100", 3306);
get_error(coroutine co = nil)
获取错误信息字符串。
参数:
co
: 协程对象,默认为当前协程
返回值:
string
: 错误信息字符串,如果没有错误则返回nil
示例:
string error_msg = last_error.get_error();
if (error_msg) {
write("发生错误: " + error_msg);
}
get_error_with_stack(coroutine co = nil)
获取带堆栈信息的错误对象。
参数:
co
: 协程对象,默认为当前协程
返回值:
LastError
: 错误对象,包含错误信息和堆栈信息
示例:
LastError error_obj = last_error.get_error_with_stack();
if (error_obj) {
write("错误消息: " + error_obj.msg);
write("调用堆栈: " + sprintf("%O", error_obj.stack));
}
警告处理 API
set_warning(string msg, ...)
设置警告信息,支持格式化字符串。
参数:
msg
: 警告信息格式字符串...
: 格式字符串的参数
示例:
last_error.set_warning("配置文件 %s 使用了过时的参数", "config.ini");
get_warning(coroutine co = nil)
获取警告信息字符串。
参数:
co
: 协程对象,默认为当前协程
返回值:
string
: 警告信息字符串,如果没有警告则返回nil
get_warning_with_stack(coroutine co = nil)
获取带堆栈信息的警告对象。
参数:
co
: 协程对象,默认为当前协程
返回值:
LastWarning
: 警告对象,包含警告信息和堆栈信息
配置管理 API
set_is_write_error(bool val)
设置是否将错误输出到控制台。
get_is_write_error()
获取是否将错误输出到控制台的状态。
set_is_write_warning(bool val)
设置是否将警告输出到控制台。
get_is_write_warning()
获取是否将警告输出到控制台的状态。
set_is_strict(bool val)
设置是否启用严格模式。启用严格模式后,如果上一个错误没有处理,设置新错误会触发异常。
get_is_strict()
获取是否启用严格模式的状态。