H3 库错误处理完全指南:H3Error 返回码机制、错误码表与 describeH3Error 用法
GIS【免费下载链接】h3Hexagonal hierarchical geospatial indexing system项目地址https://gitcode.com/gh_mirrors/h3/h3点击查看免费下载H3Hexagonal hierarchical geospatial indexing system将地球划分为多级六边形网格是一个纯 C 实现的地理空间索引库。在调用 H3 的众多索引、遍历与多边形填充 API 时如何稳健地识别参数越界索引非法内存不足等失败场景是每个接入方都必须解决的问题。本篇指南以 website/docs/library/errors.md 为骨架结合 h3api.h.in 与 h3Index.c 等源码系统讲解 H3 的H3Error返回码类型、20 个错误码的确切含义、describeH3Error的底层实现与命令行验证方式。读完本文你将能写出健壮的 H3 调用代码并正确区分、诊断并处理 H3 的各类错误。一、为什么 H3 需要显式错误返回H3 在设计中尽量对系统故障或意外输入保持鲁棒但有些情况确实无法恢复。H3 的应对方式是向调用方返回一个错误码error code而不是悄悄吞掉异常或在输出参数中留下无法区分失败与无输出的值。在早期的 H3 版本中不少公开函数以void作为返回类型这直接排除了用返回值指示错误的可能性而输出参数在很多场景下又无法区分错误态与正常的空结果。为此H3 v4 采纳了 dev-docs/RFCs/v4.0.0/error-handling-rfc.md2020 年 6 月提出、已接受的 RFC中的方案凡可能因输入域问题domain issues或内部错误而失败的公开函数统一以返回码形式报告错误。该 RFC 还对比了setjmp/longjmp、GetError、错误参数引用等备选方案最终选择了返回码模式主要原因是H3 的 API 面向多语言绑定binding而setjmp在其他语言中普遍不可用返回码让函数签名本身即可表明返回的是状态促使调用方习惯性检查错误与其他语言生态如 Java 的异常机制衔接自然——绑定层负责把错误码翻译为各语言惯用的错误机制。二、最简示例如何检查 H3 调用是否成功官方文档给出的标准调用模式如下。H3 函数把结果写入调用方提供的输出参数同时用返回值报告状态H3Error err; H3Index result; err latLngToCell(lat, lng, res, result); if (err) { fprintf(stderr, Error: %d, err); }要点说明latLngToCell的原型定义于 h3api.h.inH3Error latLngToCell(const LatLng *g, int res, H3Index *out)其中经纬度以弧度表示的LatLng结构体传入err为 0 表示成功E_SUCCESS非零值则对应具体的错误码如果想忽略错误可以只调用函数而不接收返回值返回值被丢弃但这通常只适合已事先用isValidCell等函数验证过输入的场景若需要更可读的报错信息可进一步调用describeH3Error(err)把错误码转成字符串参见后文。从源码结构看这类先校验、再调用的模式在官方 CLI 工具中大量使用例如 src/apps/filters/h3.c 中latLngToCell子命令先解析参数、再调用库函数并直接返回err最终由统一的分发逻辑打印错误信息。三、H3Error 类型32 位返回码的设计约束H3Error是大多数 H3 公开函数的返回类型。根据 h3api.h.in 的定义typedef uint32_t H3Error;它是一个 32 位无符号整数类型并约定以下性质H3Error为 32 位整数即uint32_t值为 0 表示成功无错误没有任何错误码会置最高位most significant bit由此推论没有任何错误码会设置H3Index中 Mode 位段Mode bit field对应的位。最后一条性质非常关键H3Index是 64 位无符号整数见 h3api.h.in其低 4 位用于存储 Mode0cell、1directed edge、2undirected edge、3vertex可通过isValidIndex判定。由于H3Error的最高位恒为 0应用层可以把错误码与结果索引混用在同一缓冲区中——例如先把结果写入 buffer再把错误码复制进去二者不会互相污染 Mode 位段从而便于统一处理错误与结果。RFC 文档中明确记录了这一点32 bit return codes with the high bit never set allows for mixing error codes and resulting indexes if desired by the application, after copying the error codes into the result buffer.四、错误码总表20 个 H3Error 值的含义错误码由 h3api.h.in 中的H3ErrorCodes枚举定义其数值与名称一一对应。下表完整列出全部 20 个错误码值名称描述0E_SUCCESS成功无错误1E_FAILED操作失败但没有更具体的错误码可用2E_DOMAIN参数超出可接受范围在无更具体错误码时使用3E_LATLNG_DOMAIN纬度或经度参数超出可接受范围4E_RES_DOMAIN分辨率resolution参数超出可接受范围5E_CELL_INVALIDH3Index单元格参数无效6E_DIR_EDGE_INVALIDH3Index有向边directed edge参数无效7E_UNDIR_EDGE_INVALIDH3Index无向边undirected edge参数无效8E_VERTEX_INVALIDH3Index顶点vertex参数无效9E_PENTAGON遇到五边形畸变pentagon distortion算法无法处理10E_DUPLICATE_INPUT参数中出现重复输入算法无法处理11E_NOT_NEIGHBORS两个H3Index单元格参数不是邻居12E_RES_MISMATCH两个H3Index单元格参数分辨率不兼容13E_MEMORY_ALLOC必要的内存分配失败14E_MEMORY_BOUNDS提供的内存边界不够大15E_OPTION_INVALIDMode 或 flags 参数无效16E_INDEX_INVALIDH3Index参数无效17E_BASE_CELL_DOMAIN基础单元格编号base cell number超出可接受范围18E_DIGIT_DOMAIN子级索引数字child indexing digits无效19E_DELETED_DIGIT子级索引数字指向一个已删除的子序列4.1 如何判断这些错误码在实际代码中何时出现错误码的使用遍布整个库从源码中可以找到大量佐证例如E_DUPLICATE_INPUT在 cellsToMultiPoly.c 与 h3Index.c 中返回对应compactCells遇到重复输入、多边形转换遇到重复单元格等场景E_NOT_NEIGHBORS在 directedEdge.c 中返回对应cellsToDirectedEdge对两个不相邻单元格建边等场景E_OPTION_INVALID在 localij.c 与 polygon.c 中返回对应cellToLocalIj传入非法 mode、polygonToCells传入非法 flags 等场景E_RES_DOMAIN在 h3Index.c 中getIndexDigit对res 1 || res MAX_H3_RES的情况返回此错误码。4.2 应用方如何处理新增错误码H3 库未来可能随时增加新的错误消息。应用代码遇到无法识别的错误码时应当按E_FAILED值 1对待以保证向前兼容。同时C 库提供了一个便利的哨兵值H3_ERROR_END——它是最后一个已定义错误码的后一位one past the last defined error message见 h3api.h.in 中// Sentinel value; not a real error.的注释。H3_ERROR_END方便在迭代所有错误消息时作为上界使用。五、describeH3Error把错误码翻译成可读字符串describeH3Error是库中与错误处理直接配套的实用函数声明于 h3api.h.inconst char *H3_EXPORT(describeH3Error)(H3Error err);其实现位于 h3Index.cstatic char *H3ErrorDescriptions[] { /* E_SUCCESS */ Success, /* E_FAILED */ The operation failed but a more specific error is not available, /* E_DOMAIN */ Argument was outside of acceptable range, /* E_LATLNG_DOMAIN */ Latitude or longitude arguments were outside of acceptable range, /* E_RES_DOMAIN */ Resolution argument was outside of acceptable range, /* E_CELL_INVALID */ Cell argument was not valid, /* E_DIR_EDGE_INVALID */ Directed edge argument was not valid, /* E_UNDIR_EDGE_INVALID */ Undirected edge argument was not valid, /* E_VERTEX_INVALID */ Vertex argument was not valid, /* E_PENTAGON */ Pentagon distortion was encountered, /* E_DUPLICATE_INPUT */ Duplicate input, /* E_NOT_NEIGHBORS */ Cell arguments were not neighbors, /* E_RES_MISMATCH */ Cell arguments had incompatible resolutions, /* E_MEMORY_ALLOC */ Memory allocation failed, /* E_MEMORY_BOUNDS */ Bounds of provided memory were insufficient, /* E_OPTION_INVALID */ Mode or flags argument was not valid, /* E_INDEX_INVALID */ Index argument was not valid, /* E_BASE_CELL_DOMAIN */ Base cell number was outside of acceptable range, /* E_DIGIT_DOMAIN */ Child digits invalid, /* E_DELETED_DIGIT */ Deleted subsequence indicates invalid index }; const char *H3_EXPORT(describeH3Error)(H3Error err) { // err is always non-negative because it is an unsigned integer if (err H3_ERROR_END) { return H3ErrorDescriptions[err]; } return Invalid error code; }实现要点返回的字符串由库内部静态分配调用方不应free它由于H3Error是无符号整数err恒为非负当err H3_ERROR_END时直接索引静态描述数组否则返回Invalid error code该函数在官方 CLI 中用于统一报错。例如 src/apps/filters/h3.c 的分发宏在子命令返回非零错误时打印if (err ! 0) { fprintf(stderr, Error %i: %s\n, err, H3_EXPORT(describeH3Error)(err)); }5.1 用官方测试验证行为仓库中的 testDescribeH3Error.c 针对该函数设计了多组断言可直接作为行为契约参考E_SUCCESS对应字符串SuccessE_CELL_INVALID对应字符串Cell argument was not valid任意未知错误码如9001、H3_ERROR_END本身以及H3_ERROR_END 1均返回Invalid error code用于防止有人误把错误码追加到哨兵值之后遍历E_SUCCESS到H3_ERROR_END之间的所有错误码断言它们都不是有效的 H3 索引!isValidIndex(e)这正好验证了上文H3Error 不会触碰 Mode 位段、不会与索引混淆的设计。5.2 通过 CLI 快速上手仓库为 CLI 工具配置了端到端测试 tests/cli/describeH3Error.txt可以直接据此体验describeH3Error的用法describeH3Error -e 0 Success describeH3Error -e 10 Duplicate input describeH3Error -e 13 Memory allocation failed describeH3Error -e 100 Invalid error code即命令行工具h3提供了describeH3Error子命令传入错误码数字-e即可在终端看到对应的人类可读描述是调试 H3 程序时最快捷的手段。六、编程实践健壮地调用 H3 API6.1 两种推荐的调用模式模式一标准检查推荐H3Error err; H3Index result; err latLngToCell(lat, lng, res, result); if (err) { fprintf(stderr, Error %d: %s\n, err, describeH3Error(err)); /* 根据错误码决定恢复策略如纠正输入、降级处理或向上传播 */ return err; } /* 此时 result 才是可信的 */模式二先验证后调用适合热路径与 CLI 工具H3 提供了isValidCell、isValidIndex、isValidDirectedEdge、isValidVertex等布尔校验函数声明于 h3api.h.in。其中isValidIndex的实现是三种类型校验的并集见 h3Index.cint H3_EXPORT(isValidIndex)(H3Index h) { return H3_EXPORT(isValidCell)(h) || H3_EXPORT(isValidDirectedEdge)(h) || H3_EXPORT(isValidVertex)(h); }RFC 文档区分了两类返回布尔值的函数校验类函数validation functions如isValidCell可直接以错误码表达校验失败属性查询类函数property inspection functions如isResClassIII、isPentagon返回值在索引无效与属性为假之间存在歧义因此 H3 的 CLI 实现如 src/apps/filters/h3.c 中的isResClassIII子命令会先调用isValidIndex判合法性不合法则返回E_INDEX_INVALID合法后再查询属性。这种先验证、后查询的模式值得在自己的代码中沿用。6.2 错误码分类速查据源码可推断的常见映射错误码常见触发场景源码佐证E_LATLNG_DOMAIN经纬度超出可接受范围如latInfinityarea.c 等经纬度相关实现E_RES_DOMAIN分辨率参数越界如res-1或res15h3Index.cE_CELL_INVALID传入非法单元格索引如index0h3Index.c 一带的构造校验E_DUPLICATE_INPUT集合中存在重复索引h3Index.c、cellsToMultiPoly.cE_NOT_NEIGHBORS两个索引不相邻时建边directedEdge.cE_OPTION_INVALIDMode/flags 参数非法localij.c、polygon.cE_MEMORY_ALLOC内部内存分配失败RFC 示例kRing(...) E_MEMORY_ALLOC上表中部分行依赖 RFC 文档给出的示例调用如latLngToCell(latInfinity, lng0, res0, out) E_LATLNG_DOMAIN这些示例来自 error-handling-rfc.md可作为编写单元测试时的预期参考。七、面向语言绑定的错误码翻译约定H3 的 C API 设计初衷是供多种语言绑定使用库中 scripts/binding_functions.sh 与 scripts/binding_functions.ps1 即用于辅助生成各语言绑定。官方文档对绑定层给出如下约定绑定应将错误码翻译为各自语言惯用的错误处理机制。例如 Java 绑定会把错误码转换为 Java 异常RFC 中给出了H3Exception携带errorCode并据码生成消息的示例只要可能应保留原始错误码实在无法保留时允许省略elide语言绑定的错误消息应按照该语言的习惯格式书写。这解释了为什么 C 层选择返回码而非setjmp返回码可以被各语言绑定无歧义地翻译成异常、错误对象或其他惯用机制而setjmp无法做到。八、小结与进一步阅读H3 的错误处理体系可以概括为三句话统一返回码可能失败的公开函数一律返回H3Erroruint32_t0 表示成功码值有约束所有错误码最高位为 0因此永远不会与H3Index的 Mode 位段冲突可安全地与结果索引混合存放向前兼容应用必须容忍未知错误码并按E_FAILED处理H3_ERROR_END作为迭代上界describeH3Error负责输出可读描述。若要继续深入推荐阅读以下仓库内资料错误处理设计决策的完整论证error-handling-rfc.md含各备选方案的对比与示例错误码结果错误码与 API 声明的权威来源h3api.h.indescribeH3Error实现与其行为测试h3Index.c、testDescribeH3Error.cCLI 端的错误输出与测试h3.c、describeH3Error.txt。赞分享GIS【免费下载链接】h3Hexagonal hierarchical geospatial indexing system项目地址https://gitcode.com/gh_mirrors/h3/h3点击查看免费下载相关推荐H3错误处理完全指南轻松掌握describeH3Error函数和H3ErrorCodesH3错误处理完全指南轻松掌握describeH3Error函数和H3ErrorCodes H3是一个六边形分层地理空间索引系统在处理地理空间数据时可能会遇到GISlibgit2 错误处理机制全解错误码、错误 API 与最佳实践libgit2 错误处理机制全解错误码、错误 API 与最佳实践 libgit2 是一个可嵌入应用中的 Git 纯 C 实现库其错误处理遵循经典 POSIX开发工具免费零安装Inpaint-web 在浏览器里搞定图像修复与超分辨率免费零安装Inpaint web 在浏览器里搞定图像修复与超分辨率 想去掉照片里的路人、把模糊图放大变清晰浏览器图像修复可以不用装软件完成。Inpaint图像处理AI 应用前端上一篇PPT Master 动画与切换完全教程203 种原生动画 48 种切换让 PPT 真正动起来下一篇初识msModelSlim为什么昇腾大模型压缩工具成为AI部署新宠创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考