模块契约错误 API

当前错误

每个执行上下文拥有一个当前错误。普通线程默认使用线程上下文;协程和任务调度器切换自己的错误槽,因此迁移协程不会污染承载线程或其他任务。原生线程退出时仍留在默认错误槽中的对象会自动释放,C 扩展线程不需要为防止泄漏而强制清错。

  • xrtGetError 借用当前错误。
  • xrtTakeError 取走当前引用并清空错误槽。
  • xrtSetError 增加传入对象的引用并替换当前错误,传入 NULL 等价于清除。
  • xrtClearError 清除并释放当前引用。

常见失败不需要手工创建、设置再释放临时对象:

需要动态消息时选择 XRT_MODULE_ERROR_FORMAT:

两个 Helper 都会创建不可变错误并直接移交给当前上下文。xrtSetErrorFormat 使用 printf 规则,支持任意长度消息,拒绝具有写入副作用的 %n,并把 NULL 格式报告为参数错误。 格式化测量与写入和字符串格式化模块复用同一内部实现,不重复维护解析器。构造失败时保留 无分配的 XERR_MEMORY,不会发布部分消息。

成功操作不隐式清除旧错误。调用方只能在函数通过返回值报告失败后读取当前错误;需要长期保留时使用 xrtTakeError 或 xrtErrorRef。

错误处理器

xrtSetErrorHandler 安装一个进程级观察处理器。设置错误时,XRT 先更新当前错误,再使用并发一致的“回调+用户数据”快照通知处理器。回调只借用错误对象,可以读取或增加引用;处理器内部再次设置错误不会递归调用自身。

处理器在隔离的错误边界内执行。处理器调用的 XRT API 即使失败,或者处理器主动设置、清除、取走当前错误,回调返回后仍会恢复正在通知的主错误。处理器需要保留主错误时仍应调用 xrtErrorRef;通过 xrtTakeError 取得的引用由处理器自行释放。

处理器用于日志、调试和语言运行时桥接,不能替代函数返回值。并发替换处理器时,已经开始的通知可以使用替换前的完整快照;调用方必须让旧处理器的用户数据存活到全部在途回调结束。

设计契约

xerror 是不可变、可跨线程持有的结构化错误对象。错误由通用类别、稳定域、模块代码、系统代码、操作名、UTF-8 消息、可选数据和原因链组成。通用类别用于跨模块控制流,域与代码用于模块精确判断,消息只用于展示。

Core 错误 API 不依赖容器、字符串模块或 printf 运行时。需要结构化附加数据的模块应为 Data 定义稳定格式,或在自己的结果对象中保存详细字段,不能要求调用方解析展示消息。 动态消息格式化是独立的 error_format 便利模块,不增加最小 Core 的代码体积。

通用类别

  • XERR_ARGUMENT、XERR_TYPE、XERR_VALUE、XERR_RANGE:输入不符合契约。
  • XERR_STATE:对象或运行时状态不允许当前操作。
  • XERR_MEMORY:内存不足。
  • XERR_IO、XERR_NOT_FOUND、XERR_EXISTS、XERR_PERMISSION:系统资源错误。
  • XERR_AGAIN:当前无法推进,但对象仍有效,调用方可等待后重试。
  • XERR_TIMEOUT、XERR_CANCELLED、XERR_CLOSED:等待终止或资源关闭原因。
  • XERR_PROTOCOL、XERR_UNSUPPORTED、XERR_INTERNAL:协议、能力或内部不变量错误。

XERR_NONE 只表示没有错误,不能用于创建错误对象。

字段与原因链

xrtErrorKind、xrtErrorDomain、xrtErrorCode、xrtErrorSystemCode、xrtErrorOperation、xrtErrorMessage、xrtErrorData 和 xrtErrorCause 返回不可变字段。空错误指针返回零值或空字符串。

xrtErrorIs 沿原因链查找通用类别。xrtErrorFind 沿原因链精确匹配域和代码。两者返回借用指针,未找到时返回 NULL。

OOM 保证

参数、状态、范围和内存不足等核心错误使用静态不可变对象。即使自定义分配器 已经失败,xrtMalloc() 仍能无分配地设置 XERR_MEMORY,错误构造失败也 不会用第二次分配覆盖这个原因。

范例

结构化原因链范例位于 examples/core/error/main.c,动态消息范例位于 examples/core/error_format/main.c。

旧版资产决策

旧版只保存线程局部 UTF-8 字符串,并通过 bFree 把消息所有权交给错误槽; 模块只能依赖消息文本,上层宿主也无法稳定区分错误类别。新版保留线程隔离、 设置/读取/清除的简短手感和进程级观察回调,替换为不可变引用对象、稳定域与 代码、系统代码、操作、机器数据和原因链。

旧 test_base.h 的字符串错误、UTF-16/UTF-32 转换入口不进入核心错误层; 字符转换由 Charset 完成,模块直接构造 UTF-8 结构化错误。当前回归额外覆盖 错误深复制、原因查询、并发线程隔离、线程退出析构、协程执行上下文和 OOM 无分配报告。

附录:Core 并集函数

本文件的门禁并集包含 core 模块全部四个头(features/core/error/memory),因此下列内存、引用与版本函数在本文件同样成节;完整模块语境见 core.md 与 memory.md。

Windows 动态嵌入的最终线程存储退役

bool xrtRuntimeRetireThreadStorage(void) 退役当前 XRT 实例注册的内部 FLS/TLS 槽,包括堆缓存、默认错误、默认临时 arena、TinyCC 随机/故障注入状态、 Future 通知与线程/协程借用槽。清理顺序是 payload → error → heap → borrowed, 不依赖惰性初始化的先后。它不会禁用正常运行期间的线程缓存。

宿主必须先关闭所有调用/回调入口,等待 XRT 工作结束,释放外部持有对象、任务、 动态线程键等资源,并在各自线程清理动态键、解绑执行上下文。宿主线程和 Fiber 可以保持存活,但不得再进入该实例,也不得与退役并发退出或销毁 Fiber。 之后,在代码和分配器仍驻留时、DllMain 和加载器锁之外调用此接口,成功返回后 才可卸载代码。FLS 槽释放会同步析构所有 Fiber 的非空值;先保留错误和堆的依赖, 最后移除保护槽。不会在持有注册表锁时执行这些析构。

这是终态操作,不是 reset:成功后重复调用返回 true;失败可能已经完成部分清理, 只能保持代码驻留并重试,不能恢复业务或调用 XRT 错误接口。新槽注册被关闭, 重入/并发退役返回 false。本接口自身不分配内存、不访问错误 TLS。 非 Windows 平台当前返回 false 且不改变状态;不宣称支持 POSIX 共享库退役。

此接口只消除内部线程存储的代码引用,不收集对象图、不判定外部引用是否已经释放, 不清空中央堆 span 或其他模块级资源。对象和代码租约的正确性仍由宿主负责。

版本与公共宏

名称含义
XRT_VERSION_MAJOR主版本号
XRT_VERSION_MINOR次版本号
XRT_VERSION_PATCH修订版本号
XRT_VERSION_TEXT零结尾版本字符串
XRT_NPOSsize_t 查找接口共用的未找到值
XRT_API静态库、导出库和导入库共用的符号规则
XRT_EXTERN_C_BEGIN / XRT_EXTERN_C_ENDC++ 调用时使用 C 链接

基础类型

int8、uint8、int16、uint16、int32、uint32、int64 和 uint64 固定宽度。ptr 是可写无类型指针,str / cstr 是可写和只读 UTF-8 零结尾字符串,bytes / cbytes 是可写和只读字节指针。

xtime 是有符号 64 位 公元 UTC 毫秒,可直接用作 FFI 和跨模块时间标量。 单调时钟不使用该类型,避免把持续时间误当成绝对日期。

资源边界

xrtresourcelimits 为解析器、压缩器、归档器和其他可能放大输入的模块提供统一边界:

字段含义
iMaxInputBytes最多消费的输入字节数
iMaxOutputBytes最多生成的输出字节数
iMaxItemBytes单个条目、字段或文件的最大字节数
iMaxEntries最大条目数
iMaxNodes最大语法树或对象节点数
iMaxDepth最大嵌套深度
iMaxCompressionRatio最大输出输入比;输入为零时由具体模块拒绝非空输出
iFlags显式允许符号链接、硬链接、设备文件或外部实体

允许危险资源必须显式设置 XRT_RESOURCE_ALLOW_SYMLINKS、 XRT_RESOURCE_ALLOW_HARDLINKS、XRT_RESOURCE_ALLOW_DEVICE_FILES 或 XRT_RESOURCE_ALLOW_EXTERNAL_ENTITIES。具体模块只解释与自身相关的标志。

借用视图

两个 View 都只借用内存,不拥有数据,也不要求末尾补零。Size == 0 时 Data == NULL 合法。XRT_BYTES_INIT / XRT_STR_INIT 用于静态聚合初始化, XRT_BYTES_LITERAL / XRT_STR_LITERAL 用于赋值和函数实参。

这四个宏按 sizeof(array) - 1 计长,只能接受编译期数组或字符串字面量, 不能用于指针:

引用计数

对象把初始计数设为一。Retain 原子加一并返回新值,Release 原子减一并 返回新值;返回零的线程负责析构对象。空指针、非正计数、复活已经归零的对象、 释放非正计数及递增 INT32_MAX 都返回 -1,且不修改计数。

这两个通用函数只保护计数,不发布对象字段、不加入 ownership freeze 域,也不 替代对象自己的并发契约。对象在交给其他线程前仍必须通过锁、原子发布或 XRT 已声明的线程安全 API 建立 happens-before。只有实际作为 ownership graph 节点计数的独立原子更新才使用 xrtOwnershipRefRetain/Release;涉及字段、回调 或析构的转换必须用一个外层 mutation scope 覆盖完整过程。

内存

全库动态内存统一走这些入口,因此 xrtSetAllocator 可以整体替换底层分配器。 At 变体(XRT_FEATURE_MEMORY_DEBUG 下提供)记录调用位置用于泄漏诊断,语义与对应基础函数一致。

结构快照与显式接管协议

xrtOwnershipSnapshotCreate/NodeCount/Node/Destroy 复用 Inspect 的同一物理图算法。 每个节点保存真实强计数、内部入边计数和可达性;不保有节点。准入回调先于该 节点的 Count/Trace,可在调用未知代码之前拒绝整个图。节点顺序是首次发现 顺序:先输入 anchor,再 internal slot,最后展开出边。重复物理身份只出现一次。 失败不修改输出;读取节点不重新扫描、不分配,销毁只释放快照记账。 调用方必须独立保持完整图静止及节点、回调代码有效,直到建立真正的保有引用。

xrtownershipadapterv1 是独立的生命周期协议,不扩展旧二函数 xrtownershipops 的内存布局。解析器须证明完整 mutation 参与与上下文能力,不能仅凭 Trace 存在 就认证。Hold/Drop 对应实际引用;Claim/Restore 以独占 token 隔离弱/raw 新准入, 允许已有合法强拥有者在 Finalize 后产生可检测的复活。Finalize 在 freeze 外运行, 其物理“已执行”状态跨撤销保留。重新判断根、检查新析构职责与 Clear 必须在同一 freeze 内完成;Clear 不能分配、失败、等待或运行用户代码。Finish 在 freeze 外 处理已准备的机械释放尾部,不得开始新的用户语义析构或发布已接管的 receiver。

XRT 提供普通 Value/backing、明确授权的对象/Handle 生命周期适配器,见 Value 文档;完整事务协调由上层实现。xrtErrorOwnershipAdapterV1 另外识别本实例的 不可变 Error/Cause DAG:文本内联拥有,Cause 只指向更早的错误,不存在回指语言 模块的边或用户回调。其 Clear 不修改不可变数据,真实 Cause 边保留到最后一次 Drop;外部错误别名因此不会反向保活模块。这不是 XRT 自动 GC,也不证明任意 原生上下文或语言模块可以回收。

析构前语义准备

xrtownershippreparationv1 与生命周期表是两个独立、不可变的描述符;Adapter 必须精确指向同一生命周期表,不能扩展旧表或把未知描述符降级为空准备职责。 Ready 在 freeze 内只读检查,Prepare 在 freeze/mutation 外运行,可正常通知 已受理的回调。READY 后必须重建完整物理图,再决定下一项准备或析构;通知可能 增加新节点或外部引用,不能继续使用通知前的可达性。每一次对象 Finalize 后也须 重新检查,防止析构新建资源后提前析构其捕获对象。

BUSY 不允许本次准备调用产生语义回调或改变拥有边,可非阻塞地尝试其他依赖。 FAILED 是显式失败,即使没有诊断对象也不能当作成功。上层应区分快照/准入失败 和语义调用失败;已经发生的通知和物理析构职责不能因撤销、分配失败或重试而重放。

旧版资产决策

新版保留旧 xrt.h / base.h 中简短类型名称、毫秒 xtime、原子引用及 无需复杂对象即可使用的风格,并补齐固定宽度、只读指针和显式借用 View。 旧 test_base.h 的有效引用边界由核心单元测试和并发测试承接;可变全局状态、 隐式字符串所有权和初始化引用计数被明确退役。

完整范例位于 examples/core/(error / memory / reference / version_limits / allocator_tour)与 examples/error/tour。

内存范围

xrtMemRangeValid() 验证半开范围 [Data, Data + Size) 的起点和末地址计算;空范围允许空指针。xrtMemRangesOverlap() 使用地址差判断两个非空范围是否重叠,不计算可能回绕的末地址。调用重叠判断前,调用方应先分别验证两个范围。

这两个函数是头文件内联的零分配基础能力,适合协议解析器、视图类型和扩展库统一执行边界检查。

设计契约

所有 XRT 动态内存最终经过同一个进程级底层分配器。默认实现使用 C 运行库分配器;嵌入方可以在第一次 XRT 分配之前替换它。首次原始分配后分配器冻结,避免同一地址由不同分配器交叉释放。安装、读取和首次分配使用同一短临界区,并发发生时只有一个顺序获胜,不会观察到撕裂配置。

xrtMalloc(0) 和 xrtCalloc(0, n) 仍返回一块可释放的非空内存。xrtRealloc(p, 0) 释放 p 并返回 NULL。所有返回地址至少按 16 字节对齐;该保证不依赖平台 C 分配器在 32 位环境下的最低对齐值。

小于等于 1024 字节的分配沿用旧版 16 字节尺寸类与 span 复用,并由每个原生 线程惰性缓存少量空闲块。缓存按批从中央链补给,超过上限时批量归还;线程退出 时通过 FLS 或 pthread key 析构完整归还。外部 C 线程无需先附加到 XRT。TLS 资源或缓存元数据申请失败只会退回中央链,不会让原本可完成的用户分配失败。 显式内存池的用户区始终从底层全局分配起点之后开始,因此首个池对象也不会与 可直接传给 xrtFree 的地址发生别名。

全局分配器

进程唯一底层分配器的安装、读取和全部派生入口。

引用计数与运行时信息

嵌入对象引用计数和版本、资源上限查询。

范例

完整范例位于 examples/core/memory/main.c。

旧版资产决策

新版保留旧 base.h / memglobal.h 已经验证的零大小处理、16 字节尺寸类、 同类原位 realloc、跨类数据保留、小块 span 复用、每线程缓存及批量中央链 交换。旧公开 xCore 分配器函数指针、线程对象内嵌缓存布局和必须显式 xrtUnit() 才能清理的状态被替换为不可见进程级堆与独立线程缓存;分配器 配置使用独立 API,模块不能直接改写全局函数指针。

旧 test_base.h 与 test_memglobal_core.h 的有效边界由 test_memory、 test_heap、test_heap_threads 和 OOM 回归承接,并新增并发分配器冻结、 32 位对齐、溢出原子失败、未附加原生线程、线程退出缓存归还和调试归属诊断。

xerrkind类型

跨模块稳定的错误类别。

值语义
XERR_NONE无
XERR_ARGUMENT参数非法
XERR_TYPE类型
XERR_VALUE值非法
XERR_RANGE范围越界
XERR_STATE状态非法
XERR_MEMORY内存分配失败
XERR_IO系统 IO 失败
XERR_NOT_FOUND未找到
XERR_EXISTS已存在
XERR_PERMISSION权限不足
XERR_AGAIN暂不可推进
XERR_TIMEOUT超时
XERR_CANCELLED已取消
XERR_CLOSED已关闭
XERR_PROTOCOL协议非法
XERR_UNSUPPORTED不支持
XERR_INTERNAL内部不变量破坏
typedef enum xerrkind { XERR_NONE = 0, XERR_ARGUMENT, XERR_TYPE, XERR_VALUE, XERR_RANGE, XERR_STATE, XERR_MEMORY, XERR_IO, XERR_NOT_FOUND, XERR_EXISTS, XERR_PERMISSION, XERR_AGAIN, XERR_TIMEOUT, XERR_CANCELLED, XERR_CLOSED, XERR_PROTOCOL, XERR_UNSUPPORTED, XERR_INTERNAL } xerrkind;

xerrordesc类型

描述一个完整错误,所有字符串在创建时复制。

字段类型语义
Kindxerrkind错误种类
Codeint32错误码
SystemCodeint32平台错误码
Domaincstr错误域
Operationcstr失败操作名
Messagecstr消息文本
Datacstr数据
Causeconst xerror*原因链
typedef struct xerrordesc { xerrkind Kind; int32 Code; int32 SystemCode; cstr Domain; cstr Operation; cstr Message; cstr Data; const xerror* Cause; } xerrordesc;

xerrorlocation类型

可选的源码位置;零值表示调用方没有提供对应信息。

字段类型语义
Filecstr文件名
Lineint32行号
Columnint32列号
typedef struct xerrorlocation { cstr File; int32 Line; int32 Column; } xerrorlocation;

xerror类型

错误对象由 XRT 管理,对外保持不可变。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。

typedef struct xerror xerror;

xerrorhandler类型

错误处理器只借用错误对象,保存时必须增加引用。 回调类型;参数与返回语义见签名及各使用方 API 节。

typedef void(*xerrorhandler)(const xerror* pError, ptr pUserData)
错误对象构建

xrtErrorBuild函数

从完整描述创建一个错误对象。

xerror* xrtErrorBuild(const xerrordesc* pDesc)

参数

参数方向约束说明
pDesc输入非空类别/域/码/操作/消息/数据/原因完整描述
返回值
返回含义失败时状态
非空拥有引用的错误对象—
NULL描述非法或 OOMXERR_ARGUMENT / XERR_MEMORY
错误
  • XERR_ARGUMENT — 描述指针非法
  • XERR_MEMORY — 对象或字段副本分配失败

范例已编译验证

error/tour · 构建 · 六字段描述逐项核对

pError = xrtErrorBuild(&Desc);
if ( (pError == NULL) ||
	(xrtErrorKind(pError) != XERR_ARGUMENT) ||
	(xrtErrorCode(pError) != 7) ||
	(strcmp(xrtErrorDomain(pError), "demo") != 0) ||

xrtErrorBuildAt函数

从完整描述和可选源码位置创建一个错误对象。

xerror* xrtErrorBuildAt(const xerrordesc* pDesc, const xerrorlocation* pLocation)

参数

参数方向约束说明
pDesc输入非空完整描述
pLocation输入允许空File/Line/Column 源码位置;空 = 无位置
返回值
返回含义失败时状态
非空带位置的错误对象—
NULL参数非法或 OOM同 xrtErrorBuild
错误
  • 同 xrtErrorBuild

范例已编译验证

error/tour · 源码位置 · 三定位器核对

Location.File = "democ.c";
Location.Line = 10;
Location.Column = 2;
pInner = xrtErrorBuildAt(&Desc, &Location);

xrtErrorCreate函数

创建一个常用错误对象。

xerror* xrtErrorCreate(xerrkind Kind, cstr sDomain, int32 iCode, cstr sMessage)

参数

参数方向约束说明
Kind输入枚举值错误类别
sDomain输入非空稳定域字符串
iCode输入—域内代码
sMessage输入非空人类可读消息
返回值
返回含义失败时状态
非空拥有引用的错误对象—
NULL参数非法或 OOM错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT / XERR_MEMORY

范例已编译验证

core/error · 原因链 · 下层错误构建

xerror* pCause = xrtErrorCreate(XERR_TIMEOUT, "example.net", 1, "connect timeout");

xrtErrorWrap函数

创建带有原因链的错误对象;内部增加原因的引用。

xerror* xrtErrorWrap(const xerror* pCause, xerrkind Kind, cstr sDomain, int32 iCode, cstr sMessage)

参数

参数方向约束说明
pCause输入非空、借用下层原因;Wrap 增加其引用
Kind输入—上层类别
sDomain输入—上层域
iCode输入—上层代码
sMessage输入—上层消息
返回值
返回含义失败时状态
非空上层错误,Cause 指向原因对象—
NULL参数非法或 OOM原因对象不受影响
错误
  • XERR_ARGUMENT / XERR_MEMORY

范例已编译验证

core/error · 原因链 · 包装后释放自己的原因引用

pError = xrtErrorWrap(pCause, XERR_IO, "example.client", 2, "request failed");
xrtErrorFree(pCause);

xrtErrorRef函数

增加错误对象引用并返回原指针。

xerror* xrtErrorRef(const xerror* pError)

参数

参数方向约束说明
pError输入非空目标错误对象
返回值
返回含义失败时状态
原指针引用 +1;须配一次 ErrorFree—
NULL参数非法或引用耗尽XERR_ARGUMENT
错误
  • XERR_ARGUMENT — pError 为空

范例已编译验证

error/tour · 共享引用 · Ref 与 Free 配对

pRef = xrtErrorRef(pError);
if ( (pRef != pError) ) {
	goto Cleanup;
}
xrtErrorFree(pRef);  /* Ref 那份 */

xrtErrorFree函数

释放错误对象引用。

void xrtErrorFree(xerror* pError)

参数

参数方向约束说明
pError输入允许空要释放的引用;归零时连同原因链释放
返回值
返回含义
无空指针是空操作

范例已编译验证

core/error · 生命周期 · 每份引用各自释放

xrtSetError(pError);
xrtErrorFree(pError);
字段访问与原因链查询

xrtErrorKind函数

返回错误类别。

xerrkind xrtErrorKind(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
xerrkind类别枚举;空指针返回 XERR_NONE

范例已编译验证

error/tour · 构建 · 构建后核对类别

(xrtErrorKind(pError) != XERR_ARGUMENT) ||

xrtErrorDomain函数

返回错误的稳定域字符串。

cstr xrtErrorDomain(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
cstr域字符串借用;空指针返回空串

范例已编译验证

error/tour · 构建 · 域核对

(strcmp(xrtErrorDomain(pError), "demo") != 0) ||

xrtErrorCode函数

返回域内错误代码。

int32 xrtErrorCode(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
int32域内代码;空指针返回 0

范例已编译验证

error/tour · 构建 · 代码核对

(xrtErrorCode(pError) != 7) ||

xrtErrorSystemCode函数

返回原生系统错误码(若错误由系统调用失败产生)。

int32 xrtErrorSystemCode(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
int32平台原生错误码;无系统码时为 0

范例已编译验证

process/open · 失败诊断 · 打开失败时打印系统码

pError != NULL ? xrtErrorSystemCode(pError) : 0

xrtErrorOperation函数

返回产生错误的操作名。

cstr xrtErrorOperation(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
cstr操作名借用;未设置时为空串

范例已编译验证

error/tour · 构建 · 操作名核对

(strcmp(xrtErrorOperation(pError), "load") != 0) ||

xrtErrorMessage函数

返回人类可读消息;永不返回 NULL。

cstr xrtErrorMessage(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
cstr消息借用;空错误返回 "(no error)"

范例已编译验证

core/error · 读取 · 未设置错误时也有安全占位

printf("error: %s\n", xrtErrorMessage(xrtGetError()));

xrtErrorData函数

返回结构化附加数据字符串(如 offset=12)。

cstr xrtErrorData(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
cstr数据字符串借用;未设置时为空串

范例已编译验证

error/tour · 构建 · 结构化数据核对

(strcmp(xrtErrorData(pError), "ctx") != 0) ) {

xrtErrorFile函数

返回错误记录的源文件名。

cstr xrtErrorFile(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
cstr文件名借用;未记录时为空串

范例已编译验证

error/tour · 源码位置 · BuildAt 的定位器之一

(strcmp(xrtErrorFile(pInner), "democ.c") != 0) ||

xrtErrorLine函数

返回错误记录的源码行号。

int32 xrtErrorLine(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
int32行号;未记录时为 0

范例已编译验证

error/tour · 源码位置 · 行号核对

(xrtErrorLine(pInner) != 10) ||

xrtErrorColumn函数

返回错误记录的源码列号。

int32 xrtErrorColumn(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
int32列号;未记录时为 0

范例已编译验证

error/tour · 源码位置 · 列号核对

(xrtErrorColumn(pInner) != 2) ) {

xrtErrorCause函数

返回原因链中的下层错误(借用)。

const xerror* xrtErrorCause(const xerror* pError)

参数

参数方向约束说明
pError输入允许空目标错误
返回值
返回含义
借用指针下层原因;链尾返回 NULL
错误
  • 无 — 链尾 NULL 是查询结果

范例已编译验证

network/proxy_dial · 链遍历 · 沿链逐层打印

pError = xrtErrorCause(pError);

xrtErrorIs函数

沿原因链查找指定类别,命中返回借用的错误。

const xerror* xrtErrorIs(const xerror* pError, xerrkind Kind)

参数

参数方向约束说明
pError输入允许空链起点
Kind输入—要匹配的类别
返回值
返回含义
借用指针链上第一个该类别的错误
NULL链上无该类别(查询结果,不设错)
错误
  • 无 — 未命中是查询结果

范例已编译验证

core/error · 类别判定 · 判断失败是否由超时引起

xrtErrorIs(xrtGetError(), XERR_TIMEOUT) != NULL ? "yes" : "no");

xrtErrorFind函数

沿原因链查找完全匹配的错误域和代码,返回借用的错误对象。

const xerror* xrtErrorFind(const xerror* pError, cstr sDomain, int32 iCode)

参数

参数方向约束说明
pError输入允许空链起点
sDomain输入非空要匹配的域
iCode输入—要匹配的代码
返回值
返回含义
借用指针链上第一个域 + 代码完全匹配的错误
NULL未命中(查询结果,不设错)
错误
  • 无 — 未命中是查询结果

范例已编译验证

error/tour · 链查找 · 命中内层 / 未命中为空

pFound = (xerror*)xrtErrorFind(pError, "inner", 42);
pMiss = xrtErrorFind(pError, "inner", 99);
当前执行上下文错误

xrtGetError函数

返回当前执行上下文借用的错误对象。

const xerror* xrtGetError()

参数

参数方向约束说明
无——无参数
返回值
返回含义
借用指针线程错误槽中的对象;借用有效期到下一次本线程错误设置
NULL无错误
错误
  • 无 — 空槽返回 NULL 是查询结果

范例已编译验证

error/tour · 读取 · 设置后立即读取核对

if ( (xrtGetError() == NULL) ||
	(xrtErrorKind(xrtGetError()) != XERR_TIMEOUT) ) {

xrtTakeError函数

取走当前执行上下文的错误对象。

xerror* xrtTakeError()

参数

参数方向约束说明
无——无参数
返回值
返回含义失败时状态
非空拥有引用;槽被清空,调用方负责 ErrorFree—
NULL槽为空纯取走,不设置错误
错误
  • 无 — 空槽返回 NULL 是查询结果

范例已编译验证

data/json_tour · 取走 · 解析失败后取走向法定位

((pError = xrtTakeError()) == NULL) ||
!xrtJsonErrorLocation(pError, &Location) ||

xrtSetError函数

将错误对象设置到当前执行上下文,函数会增加引用。

void xrtSetError(const xerror* pError)

参数

参数方向约束说明
pError输入允许空要设置的错误;空 = 清除
返回值
返回含义
无槽持有自己的引用;调用方仍须释放自己的引用(“SetError 不偷引用”)

范例已编译验证

core/error · 设置 · 设置后立即释放自己的引用

xrtSetError(pError);
xrtErrorFree(pError);

xrtSetErrorTake函数

将错误对象所有权转移到当前执行上下文,调用后不得继续使用原引用。

void xrtSetErrorTake(xerror* pError)

参数

参数方向约束说明
pError输入允许空要转移的错误;空 = 清除
返回值
返回含义
无所有权转移;原指针此后无效

范例已编译验证

error/tour · 所有权转移 · 转移后置空原指针

xrtSetErrorTake(pTaken);
pTaken = NULL;  /* 所有权已转移,不得继续使用 */

xrtSetErrorInfo函数

创建常用错误并直接设置到当前执行上下文。

void xrtSetErrorInfo(xerrkind Kind, cstr sDomain, int32 iCode, cstr sMessage)

参数

参数方向约束说明
Kind输入—类别
sDomain输入非空域
iCode输入—代码
sMessage输入非空消息
返回值
返回含义
无一步完成创建 + 设置;OOM 时槽设置内存错误

范例已编译验证

error/tour · 便捷设置 · 四参数直设

xrtSetErrorInfo(XERR_RANGE, "demo", 5, "out of range");

xrtSetErrorKind函数

设置无分配的通用错误;NONE 清除错误,无效类别设置参数错误。

void xrtSetErrorKind(xerrkind Kind)

参数

参数方向约束说明
Kind输入—通用类别
返回值
返回含义
无零分配路径,适合热路径

范例已编译验证

error/tour · 通用错误 · 设置即触发全局 Handler

xrtSetErrorKind(XERR_TIMEOUT);  /* 触发全局 Handler 一次 */

xrtClearError函数

清除当前执行上下文的错误。

void xrtClearError()

参数

参数方向约束说明
无——无参数
返回值
返回含义
无释放槽持有的引用;后续 GetError 返回 NULL

范例已编译验证

error/tour · 清空 · 每段核对前清理基线

xrtClearError();
xrtSetErrorInfo(XERR_RANGE, "demo", 5, "out of range");

xrtSetErrorHandler函数

设置进程级错误通知处理器。

void xrtSetErrorHandler(xerrorhandler pHandler, ptr pUserData)

参数

参数方向约束说明
pHandler输入允许空每次任何线程设置错误时收到通知;空 = 注销
pUserData输入任意值原样传给处理器
返回值
返回含义
无处理器在错误设置点同步执行;不得递归设置错误

范例已编译验证

error/tour · 全局通知 · 计数通知后注销

(void)xrtSetErrorHandler(exampleHandler, NULL);
xrtSetErrorKind(XERR_TIMEOUT);  /* 触发全局 Handler 一次 */
补充参考 · 契约见公共头注释

xrtErrorOwnership函数

契约注释见公共头文件。

XRT_API xrtownershipref xrtErrorOwnership(const xerror* pError)

xrtErrorOwnershipAdapterV1函数

契约注释见公共头文件。

XRT_API const xrtownershipadapterv1* xrtErrorOwnershipAdapterV1(xrtownershipref Reference)

常量索引常量

以下常量在本页所属头文件中定义,语义见公共头注释。

常量说明
XERR_AGAIN见头文件注释
XERR_ARGUMENT见头文件注释
XERR_CANCELLED见头文件注释
XERR_CLOSED见头文件注释
XERR_EXISTS见头文件注释
XERR_INTERNAL见头文件注释
XERR_IO见头文件注释
XERR_MEMORY见头文件注释
XERR_NONE见头文件注释
XERR_NOT_FOUND见头文件注释
XERR_PERMISSION见头文件注释
XERR_PROTOCOL见头文件注释
XERR_RANGE见头文件注释
XERR_STATE见头文件注释
XERR_TIMEOUT见头文件注释
XERR_TYPE见头文件注释
XERR_UNSUPPORTED见头文件注释
XERR_VALUE见头文件注释