主题
JSON 错误码说明 - JSONError
JSON 模块多数接口在失败时返回 JSONError 枚举值(整数)。调用方应始终检查错误码,再使用返回值或句柄。
模块总览见 JSON 模块总览。
枚举定义
c
// JSON 操作错误码枚举
typedef enum {
JSON_SUCCESS = 0, // 操作成功
JSON_ERROR_INVALID_HANDLE, // 无效的句柄
JSON_ERROR_PARSE_FAILED, // JSON 解析失败
JSON_ERROR_TYPE_MISMATCH, // 类型不匹配
JSON_ERROR_KEY_NOT_FOUND, // 键不存在
JSON_ERROR_INDEX_OUT_OF_RANGE, // 索引超出范围
JSON_ERROR_UNKNOWN // 未知错误
} JSONError;未显式赋值的枚举成员从 0 起依次递增,对应整型值如下:
| 常量 | 值 | 说明 |
|---|---|---|
JSON_SUCCESS | 0 | 操作成功 |
JSON_ERROR_INVALID_HANDLE | 1 | 无效的句柄 |
JSON_ERROR_PARSE_FAILED | 2 | JSON 解析失败 |
JSON_ERROR_TYPE_MISMATCH | 3 | 类型不匹配 |
JSON_ERROR_KEY_NOT_FOUND | 4 | 键不存在 |
JSON_ERROR_INDEX_OUT_OF_RANGE | 5 | 索引超出范围 |
JSON_ERROR_UNKNOWN | 6 | 未知错误 |
各错误码详解
JSON_SUCCESS(0)
操作正常完成。此时:
- 带
err输出参数 的接口:返回值(句柄、数值等)有效,可继续使用。 - 直接返回
int的写操作接口(如JsonSetNumber):返回0表示写入成功。
JSON_ERROR_INVALID_HANDLE(1)
传入的 JSON 句柄无效,常见原因:
| 场景 | 示例 |
|---|---|
句柄为 0 | 未初始化或已当作失败结果使用 |
| 句柄已释放 | 对同一根对象重复调用 JsonFree 后仍继续操作 |
| 句柄来源错误 | 将数组句柄当作对象句柄传入 JsonGetString 等 |
| 子句柄无效 | JsonArrayAppend 的 value 参数为 0 或已释放 |
处理建议:确认句柄来自 JsonParse、JsonCreateObject、JsonCreateArray 或 JsonGetValue / JsonGetArrayItem 的成功结果,且在使用期间未提前 JsonFree。
JSON_ERROR_PARSE_FAILED(2)
JsonParse 无法将输入字符串解析为合法 JSON。
常见原因:语法错误(缺逗号、引号不匹配)、截断的响应体、非 JSON 文本(如 HTML 错误页)。
此时返回值句柄为 0,err 为 2。勿对失败句柄调用其他 JSON 接口。
JSON_ERROR_TYPE_MISMATCH(3)
当前操作与节点 实际 JSON 类型不符。
| 接口 | 典型触发条件 |
|---|---|
JsonGetNumber | 键对应值为字符串、布尔或 null,而非数字 |
JsonGetString | 键对应值为数字、对象或数组 |
JsonGetBool | 键对应值不是布尔类型 |
JsonGetSize | 句柄既不是对象也不是数组 |
JsonGetArrayItem | 句柄不是数组 |
JsonArrayAppend | 第一个参数不是数组句柄 |
JsonSetNumber / JsonSetString 等 | obj 不是对象句柄 |
JsonDeleteKey | obj 不是对象句柄 |
处理建议:先用 JsonGetValue 读取通用句柄,或确认上游 JSON 结构;类型化读取接口(JsonGetNumber 等)仅适用于类型确定的字段。
JSON_ERROR_KEY_NOT_FOUND(4)
在 JSON 对象 中找不到指定 键名。
常见于 JsonGetString、JsonGetNumber、JsonGetBool、JsonGetValue、JsonDeleteKey 等按键访问的接口。
注意:键名 区分大小写;"Name" 与 "name" 视为不同键。
JSON_ERROR_INDEX_OUT_OF_RANGE(5)
数组 下标越界。
由 JsonGetArrayItem 在 index < 0 或 index >= 数组长度 时返回。可先调用 JsonGetSize 获取长度再遍历。
JSON_ERROR_UNKNOWN(6)
未归类的内部错误。若频繁出现,请检查输入数据、句柄生命周期,并向插件维护方反馈复现步骤。
错误码的传递方式
JSON 接口分两类,错误码位置不同:
| 类型 | 代表接口 | 如何判断成功 |
|---|---|---|
err 输出参数 | JsonParse、JsonGetString、JsonGetNumber、JsonGetBool、JsonGetValue、JsonGetArrayItem、JsonGetSize、JsonStringify | err == 0(JSON_SUCCESS),且返回值有效 |
| 返回值即错误码 | JsonSetNumber、JsonSetString、JsonSetBool、JsonSetValue、JsonArrayAppend、JsonDeleteKey、JsonClear | 返回 0 表示成功;非 0 为错误码 |
err 参数可传 0 / NULL 表示不关心错误详情,但 不建议 在生产代码中忽略错误码。
示例
解析与按类型读取
cpp
int32_t err = 0;
int64_t root = ola.JsonParse(jsonStr, &err);
if (root == 0 || err != 0) {
// err == JSON_ERROR_PARSE_FAILED (2) 等
return;
}
int32_t getErr = 0;
double level = ola.JsonGetNumber(root, "level", &getErr);
if (getErr == JSON_ERROR_KEY_NOT_FOUND) {
// 键 "level" 不存在
} else if (getErr == JSON_ERROR_TYPE_MISMATCH) {
// "level" 存在但不是数字
}
ola.JsonFree(root);写操作(返回值即错误码)
cpp
int32_t rc = ola.JsonSetNumber(root, "count", 42);
if (rc != JSON_SUCCESS) {
// rc 可能为 JSON_ERROR_INVALID_HANDLE (1) 等
}遍历数组
cpp
int32_t err = 0;
int32_t n = ola.JsonGetSize(arr, &err);
if (err != 0) return;
for (int32_t i = 0; i < n; ++i) {
int32_t itemErr = 0;
int64_t item = ola.JsonGetArrayItem(arr, i, &itemErr);
if (itemErr == JSON_ERROR_INDEX_OUT_OF_RANGE) break;
// ...
}与返回值的关系
部分接口在失败时仍会返回 哨兵值,须结合错误码判断,不可单独依赖返回值:
| 接口 | 失败时的返回值 | 须同时检查 |
|---|---|---|
JsonParse | 0 | err != 0 |
JsonGetNumber | 0.0 | err != 0 |
JsonGetBool | 0(与 false 相同) | err != 0 |
JsonGetString | 0(空指针) | err != 0 |
JsonGetValue / JsonGetArrayItem | 0 | err != 0 |
JsonGetSize | 0 | err != 0(空对象/数组成功时长度也为 0,需 err == 0 区分) |
