cangjie_stdx 异常处理指南:深入解析 stdx.encoding.json 的 JsonException
标准库网络密码学并发编程【免费下载链接】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),仅供参考

相关新闻

LangChain4j 10 Skills 实战:把本地 Skills 配置改到 TaoToken 统一通道

LangChain4j 10 Skills 实战:把本地 Skills 配置改到 TaoToken 统一通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 17:40:58 阅读更多 →
深入理解Vite:核心原理与最佳实践

深入理解Vite:核心原理与最佳实践

最近在重构一个中后台项目时遇到了一个诡异的问题:生产环境构建后,某个页面的图表渲染性能下降了近50%,但开发模式下一切正常。经过排查,发现是Vite的预构建机制与第三方库的兼容性问题。这个问题让我意识到,仅仅会用v…

2026/10/15 17:40:58 阅读更多 →
64位Windows工程集成OpenSSL:lib/dll/头文件配置与避坑指南

64位Windows工程集成OpenSSL:lib/dll/头文件配置与避坑指南

简介:面向64位Windows环境下C语言开发者的OpenSSL库文件与头文件资源包,系统整理了静态库(lib)、动态链接库(dll)及配套头文件,帮助开发者在64位架构下顺利完成SSL/TLS、加密解密等安全功能的编…

2026/10/15 17:40:58 阅读更多 →

最新新闻

如何安全取消 wreq 请求?深入 HTTP/1、HTTP/2、HTTP/3 的 Cancel Safety 完整指南

如何安全取消 wreq 请求?深入 HTTP/1、HTTP/2、HTTP/3 的 Cancel Safety 完整指南

【免费下载链接】wreq An ergonomic, privacy-aware Rust HTTP Client 项目地址: https://gitcode.com/gh_mirrors/rq/wreq 点击查看 免费下载 wreq 是一个注重易用性与隐私的 Rust 异步 HTTP 客户端。在 wreq 中取消请求的方式非常统一:丢弃&#xff0…

2026/10/15 18:28:43 阅读更多 →
STM32驱动LSM303磁力计:从I2C通信到航向角校准实战

STM32驱动LSM303磁力计:从I2C通信到航向角校准实战

简介:这份资源是面向嵌入式开发初学者与STM32学习者的LSM303磁力计驱动程序包,围绕三轴磁强计数据采集与IC通信展开,可解决电子罗盘、姿态检测等场景中磁场数据读取与解析的问题。压缩包共125个文件,以35个h头文件、34个c源文件为…

2026/10/15 18:28:43 阅读更多 →
5 分钟上手 hermes-jev-skills:两条命令让 Hermes 与 Claude Code 又聪明又省钱

5 分钟上手 hermes-jev-skills:两条命令让 Hermes 与 Claude Code 又聪明又省钱

【免费下载链接】hermes-jev-skills Jev-powered model routing, memory, compaction, skill selection, computer and browser use for Hermes agents (also Claude Code and Codex) 项目地址: https://gitcode.com/gh_mirrors/he/hermes-jev-skills 点击查看 免费…

2026/10/15 18:28:43 阅读更多 →
给 Neo4j 套一层 GraphQL API:Java 实现原理与避坑指南

给 Neo4j 套一层 GraphQL API:Java 实现原理与避坑指南

简介:这是一份面向 Java 后端与图数据库开发者的 Neo4j GraphQL API 实现资源包,解决如何让 Neo4j 对外提供 GraphQL 接口的问题。其核心价值在于能把 GraphQL 查询与变更自动转换为 Cypher 语句,并在 Neo4j 上执行;既可作为依赖库…

2026/10/15 18:28:43 阅读更多 →
IoT23流量分类实战:从数据加载、特征工程到模型选型与避坑指南

IoT23流量分类实战:从数据加载、特征工程到模型选型与避坑指南

简介:这份资源面向网络安全与机器学习方向的学习者与研究人员,围绕IoT23数据集提供一套完整的网络流量异常检测与多分类实验方案,覆盖朴素贝叶斯、决策树、随机森林、逻辑回归与SVM等经典算法的对比实践,适合具备Python基础、希望…

2026/10/15 18:28:43 阅读更多 →
SX126x LoRa驱动开发实战:从寄存器配置到拉距测试

SX126x LoRa驱动开发实战:从寄存器配置到拉距测试

简介:这份资源是面向嵌入式与物联网开发者的sx126x系列LoRa模块驱动代码包,适用于基于STM32平台集成LoRa/LoRaWAN远距离无线通信功能的场景。包内共6个文件,以3个.h头文件和3个.c源文件为主,头文件负责寄存器定义、接口声明与硬件…

2026/10/15 18:27:42 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →