标准库网络密码学并发编程【免费下载链接】cangjie_stdx仓颉编程语言提供了 stdx 模块该模块提供了网络、安全等领域的通用能力。项目地址https://gitcode.com/Cangjie/cangjie_stdx点击查看免费下载导读JsonException是仓颉标准扩展库stdx.encoding.jsonjson 包中唯一的异常类负责承载 JSON 数据在解析、类型转换、序列化与下标访问过程中发生的全部异常。本文以 encoding_json_package_exceptions.md 为主体结合仓库源码完整讲解JsonException的定义、两个构造函数的用法、底层实现原理并系统梳理它在 json 包各模块中的典型抛出场景与捕获实战帮助读者在JsonValue使用中做到看得懂异常、接得住异常、处理得干净。JsonException直接继承自标准库Exception属于运行期可检查并捕获的常规异常。它服务于 json 包的核心数据模型JsonValue——即对 JSON 中 object、array、string、number、true、false、null 七种数据格式的封装参见 json 包功能总览。在 json_value_sample.md 展示的JsonValue与String互相转换流程中任何一步格式不合规都会以JsonException的形式向调用方抛出。一、类定义与继承关系JsonException的完整定义位于源码文件 src/stdx/encoding/json/json_exception.cj定义如下public class JsonException : Exception { public init() public init(message: String) }功能定位它是 JSON 包的异常类用于 JsonValue 类型使用时出现异常的场景。在 json 包的 API 体系中凡是涉及JsonValue的解析、转换与输出操作其文档注释中标注的throws JsonException均指向该异常。父类型Exception仓颉标准库异常基类源码实现细节从 json_exception.cj 可以看到类体内部通过重写受保护方法getClassName()返回字符串JsonExceptionprotected override func getClassName(): String { return JsonException }这意味着当异常被打印或转为字符串时其类型名稳定呈现为JsonException便于日志与排查定位。该类自0.17.4版本起提供两个构造函数均通过super()/super(message)直接委托给父类Exception实现。二、构造函数详解与完整示例1.init()public init()功能构造一个不包含任何异常提示信息的JsonException实例。适用于发生了 JSON 相关异常但无需附加说明的场景——例如在字符串内容校验失败时仅用于中断流程。示例原文档验证用例import stdx.encoding.json.* main() { // 创建不带消息的JsonException try { throw JsonException() } catch (e: JsonException) { println(捕获到 JsonException: ${e.message}) } }运行结果捕获到 JsonException:从输出可以看到不带消息构造的实例其message字段为空字符串。有趣的是源码中的确存在这种空消息抛出的实际用例在 native.cj 的parseJsonString实现中当检测到 JSON 字符串内部包含不允许出现的控制字符next 0x20时直接抛出JsonException()无消息表示结构非法但不提供额外文案。2.init(String)public init(message: String)功能根据指定的异常提示信息构造JsonException实例。参数message: String- 指定的异常提示信息。示例原文档验证用例import stdx.encoding.json.* main() { // 创建带消息的JsonException try { throw JsonException(JSON解析异常) } catch (e: JsonException) { println(捕获到 JsonException: ${e.message}) } }运行结果捕获到 JsonException: JSON解析异常带消息的构造函数是实际使用中的主流形式。仓库中 json 包的所有内部抛出点几乎都携带了语义明确的 message下面将分类展开这些真实抛出场景帮助你熟悉各种异常文案对应的故障原因。三、源码级抛出场景全景JsonException 何时出现通过检索 src/stdx/encoding/json 目录下各模块的throw JsonException调用点可以将异常触发场景归纳为五类分别对应 JSON 处理的五个阶段。1. 解析阶段parse输入字符串非法入口为JsonValue.fromStr(s)其实现位于 json_value.cj内部调用parseString(s)。解析主流程在 native.cj 中典型的抛出情况包括空字符串输入str.size 0时抛出JsonException(JSON string is empty.)尾随多余内容解析完首个完整 JSON 值后若跳过空白后仍有剩余字符抛出JsonException(Failed to parse JSON data.)非法字符兜底首字符不属于{、[、n、t、f、、数字或-时抛出JsonException(Failed to parse JSON data.)统一包装错误解析过程中捕获到内部异常后会通过buildParseErrorMessage构造带行列号的详细消息重新抛出JsonException(Invalid JSON data: Parse Error: [Line]: ..., [Pos]: ..., [Error]: Unexpected character: ...)——这是实践中最常见、也最易读的解析错误文案。此外字面量true/false/null的逐字符校验见 native.cj与数字格式校验禁止前导零、禁止非十进制前缀等失败时同样抛出JsonException。2. 类型转换阶段asXxx类型不匹配JsonValue提供了一组类型强转方法全部定义在 json_value.cjasNull()、asBool()、asInt()、asFloat()、asString()、asArray()、asObject()。当JsonValue的实际类型与目标类型不符时抛出对应的JsonException方法不匹配时的异常消息asNull()Failed to convert JsonValue to JsonNull.asBool()Failed to convert JsonValue to JsonBool.asInt()Failed to convert JsonValue to JsonInt.asFloat()Failed to convert JsonValue to JsonFloat.asString()Failed to convert JsonValue to JsonString.asArray()Failed to convert JsonValue to JsonArray.asObject()Failed to convert JsonValue to JsonObject.值得注意的特例是asFloat()当原值是JsonInt时会被隐式提升为JsonFloatcase jsonInt: JsonInt JsonFloat(jsonInt.getValue())不抛异常只有其他类型才会触发JsonException。因此在编写转换代码时建议先调用kind()返回 JsonKind 枚举做分支判断再调用对应的asXxx()以避免盲目转换。3. 序列化阶段write浮点数非法与嵌套过深序列化方向JsonValue转字符串的异常集中在 json_object.cj 与 write_buffer.cj非法浮点数jsonFloatToString与WriteBuffer.append(Float64)都会先调用isJsonFloatInfinite判断。该函数在 native.cj 中实现对NaN或无穷大Infinity返回true随后抛出JsonException(Failed to serialize JSON float.)。注释明确说明NaN与Infinity不是合法的 JSON 数字字面量RFC 8259原样输出会导致序列化结果无法被任何 JSON 解析器读回写嵌套深度超限checkJsonWriteDepth在 write_buffer.cj 中比较当前深度与MAX_JSON_WRITE_DEPTH常量值为 100定义于同文件第 19 行超限抛出JsonException(JSON nested depth ... exceeds maximum 100.)DataModel 转换内部错误to_json.cj 在JsonValue与DataModelserialization 包的数据模型互转时若出现无法匹配的类型抛出JsonException(Internal error: unmatched JsonValue type.)或JsonException(Internal error: unmatched DataModel type.)——这属于防御性兜底分支正常输入下不会触发。4. 下标访问阶段索引或键不存在JsonArray与JsonObject都重载了下标运算符[]数组越界在 json_object.cj 中JsonArray的[](index: Int64)在索引不存在时抛出JsonException(Index ${index} does not exist in JsonArray.)键不存在同文件 L871-L875 中JsonObject的[](key: String)在键不存在时抛出JsonException(Key ${key} does not exist in JsonObject.)。这一点与安全的get()/get(key)接口形成对比get()返回OptionJsonValue不抛异常而下标运算符[]直接抛JsonException。若不确定索引或键是否存在优先使用get()并配合match解构或先通过try/catch捕获下标访问。5. 解析嵌套深度限制parse 侧与写侧对称解析侧同样有深度上限MAX_JSON_PARSE_DEPTH 100定义于 native.cj。parseNestedJson在每次进入嵌套对象/数组时检查深度超限抛出JsonException(JSON nested depth ... exceeds maximum 100.)。这一机制用于防御深度极大的恶意 JSON 输入导致的栈溢出风险。四、实战JsonException 的捕获与处理范式结合前文的抛出场景给出一个覆盖解析 → 类型转换 → 序列化 → 下标访问完整链路的实战范式import stdx.encoding.json.* func safeParse(s: String): Unit { try { let jsonValue: JsonValue JsonValue.fromStr(s) // 类型转换前先判断 kind match (jsonValue.kind()) { case JsonKind.JsObject // 下标访问可能抛 JsonException需在 try 内完成 let obj jsonValue.asObject() if (obj.contains(name)) { println(obj[name]) } case _ println(不是对象类型) } // 序列化浮点数非法或嵌套过深时可能抛异常 println(jsonValue.toJsonString()) } catch (e: JsonException) { // 统一处理message 已携带具体原因可直接写入日志 println(JsonException: ${e.message}) } catch (e: IllegalArgumentException) { // 参数类错误如缩进参数非法单独处理 println(IllegalArgumentException: ${e.message}) } } main() { safeParse({\name\:\json\}) safeParse({\name\:) // 结构不完整触发解析异常 safeParse() // 空字符串触发 JSON string is empty. }处理建议按需捕获只有需要从异常中恢复或转化为业务提示时才显式catch (e: JsonException)若异常应终止流程直接向上抛出即可善用 messageJsonException的所有内部抛出点都提供了可读性良好的 message含具体索引、键名、行列号、超限深度值将其原样写入日志即可满足大部分排障需求区分异常来源解析、转换、序列化阶段的异常都统一为JsonException若需细分故障类型可结合调用上下文判断或在捕获后检查 message 前缀如Invalid JSON data表示解析失败参数校验异常不归 JsonExceptiontoJsonString(depth, bracketInNewLine, indent)中若depth为负数或indent含空格/制表符以外的字符抛出的是IllegalArgumentException见 json_object.cj 的validateJsonStringFormat捕获时需区分对待。五、总结JsonException是stdx.encoding.json包统一的异常出口其类定义精简两个构造函数 getClassName()重写却在解析JsonValue.fromStr、类型转换asXxx、序列化toString/toJsonString、下标访问[]与嵌套深度限制五大环节全面兜底。掌握其构造方式与各类触发场景即可在JsonValue与String互相转换的日常开发中快速定位、准确捕获并优雅处理 JSON 相关错误。深入阅读 json_exception.cj、native.cj 与 json_object.cj 源码可以进一步理解每条异常消息背后的校验逻辑。赞分享标准库网络密码学并发编程【免费下载链接】cangjie_stdx仓颉编程语言提供了 stdx 模块该模块提供了网络、安全等领域的通用能力。项目地址https://gitcode.com/Cangjie/cangjie_stdx点击查看免费下载相关推荐AI Website Cloner Template五阶段流水线全解工头模式如何指挥并行建造AI Website Cloner Template五阶段流水线全解工头模式如何指挥并行建造 AI Website Cloner TemplateAI网站克人工智能AI 技能前端网页爬虫APIJSON测试体系实战构建零代码ORM框架的质量保障系统APIJSON测试体系实战构建零代码ORM框架的质量保障系统 在快速迭代的微服务架构中后端接口的稳定性直接影响整个系统的可靠性。当我们采用APIJSON这样后端ORM低代码FastJSON异常处理大全JSONException与JSONPathException调试技巧FastJSON异常处理大全JSONException与JSONPathException调试技巧 引言你还在为JSON解析异常头疼吗 在Java开发中序列化后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考