恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

DBX 后端异常处理与结构化错误码规范:从 Agent 契约到前端展示的端到端实战指南

  • 首页
  • 资讯中心
  • /
  • DBX 后端异常处理与结构化错误码规范:从 Agent 契约到前端展示的端到端实战指南

相关资讯

Gatsby 对接 Contentful CMS:基于 gatsby-source-contentful 构建数据驱动站点实战指南 2026/9/20 12:10:31
Quasar QIntersection 组件完全指南:按需渲染、释放 DOM 与 Intersection Observer 深度实践 2026/9/20 12:10:31
Ray 文档构建中的 Sphinx autosummary 类模板:class.rst 的设计与定制指南 2026/9/20 12:10:31

最新资讯

实测降AIGC平台效果!实测下来谁更胜一筹?
RIOT xtimer_usleep 精度测试应用解析:从源码到示波器验证的完整实战指南
enzyme 中 `.not(selector)` 方法详解:如何过滤出所有不匹配选择器的节点
React Native Elements 主题定制完全指南:从 containerStyle 到 ThemeProvider 的组件样式体系
毕业论文知识图谱构建:SpringBoot+Vue+Neo4j实战
TiXL 的 ScreenCapture 运算符:基于 DXGI 的实时屏幕捕获与录屏实战指南

今日推荐

BrewUI:给Homebrew套上图形界面,让macOS软件包管理更简单
BrewUI:让Homebrew包管理变得可视化与高效
公式与文本对齐全攻略:从Word到LaTeX的实用技巧

本周热门

BrewUI:给Homebrew套上图形界面,让macOS软件包管理更简单
BrewUI:让Homebrew包管理变得可视化与高效
公式与文本对齐全攻略:从Word到LaTeX的实用技巧

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

DBX 后端异常处理与结构化错误码规范:从 Agent 契约到前端展示的端到端实战指南

发布时间:2026/9/20 12:10:31
DBX 后端异常处理与结构化错误码规范:从 Agent 契约到前端展示的端到端实战指南 DBX 后端异常处理与结构化错误码规范从 Agent 契约到前端展示的端到端实战指南【免费下载链接】dbx15MB轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lightweight, cross-platform database client. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server and more.项目地址: https://gitcode.com/t8y2/dbx本文以 DBX 仓库中已落地的错误处理体系为主线系统讲解 Agent v2 类型化错误的解码、稳定错误码 catalogBackendErrorv1 envelope、脱敏边界、Tauri/HTTP/多语句三种传输通道以及前端本地化展示与 Session/Runtime 恢复规则。读完本文你将掌握如何在 DBX 中新增一个后端错误码、如何正确构造公共错误对象、如何编写恢复策略与前端翻译测试以及为什么从错误文本推断分类是一条红线。一、设计目标与整体分层DBX 的后端错误处理体系解决三个核心问题让恢复逻辑依赖可验证的类型恢复动作保留 Session、隔离 Session、替换 Runtime只由 Rust 侧的类型化事实驱动绝不从错误文本猜测让对外错误身份稳定每个错误都有永久保留、不可复用的code与messageKey错误码可以废弃但不能改义保留经过公共边界脱敏的驱动诊断信息数据库厂商返回的原始错误正文如relation does not exist、ORA-00942可以透传到前端但凭据、URL、Session 标识等敏感内容必须在公共边界被替换或删除。文档明确说明本文描述的是现有实现不引入新的 Agent Protocol V3结构化错误是 Agent Protocol v2 的可选 capabilitystructured_error_v1。体系共分六层各层职责单一对应 docs/backend-error-handling.md层职责关键产物Agent只报告事实category、stage、operationOutcome、sessionDisposition及 JDBC 诊断字段RustAgentCallError解码 Agent v2 结构化错误类型化错误枚举见 agent_driver.rsRecoveryPolicy依据类型化错误与操作范围决策保留/隔离 Session、替换 Runtime见 agent_recovery.rsBackendErrorcatalog映射稳定code/messageKey/白名单参数/安全诊断v1 envelope见 backend_error.rs查询层与传输边界生成并携带公共错误对象不重复分类QueryExecutionError::into_backend_error、Tauri/HTTP 适配前端本地化摘要与 detail 展示normalizeBackendError、translateBackendError这种分层带来的直接约束是查询层、Tauri、HTTP 和多语句结果只负责携带BackendError对象不重复做分类分类的唯一入口在 Rust 侧。二、Agent 调用契约与类型化入口Agent runtime 必须完成 Protocol v2 handshake 并支持multi_session。调用方通过call_typed拿到类型化结果若 Agent 声明了structured_error_v1RPC 失败时返回AgentCallError::Structured否则进入Legacy兼容路径。超时、取消、传输失败和契约不满足分别对应AgentCallError的Timeout、Canceled、Transport和ContractViolation变体见 agent_driver.rs 附近的枚举定义。业务代码应使用类型化入口let result client.call_typed::Response(method, params, timeout, cancel).await; if let Err(error) result { let decision RecoveryPolicy::decide(error, RecoveryScope::UserOperation); // 只执行 Session/Runtime 恢复不重放当前用户 SQL。 }AgentRuntimeClient::call和AgentCallError::into_legacy_string仅用于尚未迁移的字符串边界。旧字符串只有在try_agent_error_from_legacy能证明其来自 Agent 调用通道时才恢复为 Agent 错误不要在query、schema、connection、keepalive或 UI 中新增任何文本分类规则——这是整个体系反复强调的红线MySQL/SQL Server 的专用 batch executor 目前仍停留在字符串驱动边界原因正是驱动层尚未提供可验证的 typed failure facts。Agent 侧的类型化事实Agent 上报的核心事实枚举位于 agent_driver.rs包括AgentSessionDispositionKeep保留、Quarantine隔离、ReplaceRuntime替换 RuntimeAgentErrorCategoryConnection、Sql、Resource、Protocol以及超时/取消等类别AgentErrorStageRequest、Checkout、Connect、Validate、Execute、Fetch、Cancel、CloseAgentOperationOutcomeNotStarted操作明确未开始、Unknown结果未知。这些枚举的组合关系哪些 category/stage/outcome 组合是合法的在AgentErrorContext与valid_agent_error_combination中定义非法组合在 catalog 映射时会被归类为ContractInvalidDBX-JDBC-5002而不是被翻译成某个看似合理的错误码。三、公共错误对象BackendError v1 envelopeRust 侧BackendError的字段全部保持私有只能通过 catalog 构造器生成目的是防止code、messageKey与参数声明三者漂移见 backend_error.rs。序列化到 JSON 时使用 camelCase{ version: 1, code: DBX-JDBC-4001, messageKey: backendErrors.jdbc.sqlFailed, messageParams: { stage: execute }, source: jdbcAgent, origin: { subsystem: database, adapter: native }, operationOutcome: unknown, detail: relation missing_table does not exist, errorPosition: { line: 1, column: 15, offset: 14 }, diagnostics: { category: sql, stage: execute, sqlState: 42P01, vendorCode: 0, exceptionClass: java.sql.SQLException } }字段语义与约束version当前为1。新增可选字段可以保持 v1改变已有字段的类型、必填性、语义或删除字段时必须升级版本。version表示 envelope 版本不代表 Agent Protocol 版本。code/messageKey发布后永久保留不能复用或改义。废弃错误码只能停止新增使用不能重新分配给其他含义废弃时保留旧 locale 与兼容映射。sourcev1 兼容字段表示旧错误来源jdbcAgent、jdbcAgentLegacy、legacyBackend新代码改用origin描述子系统。客户端不能因为未知的 source/origin 值而丢弃整个 envelope。origin可扩展元数据至少包含subsystemdatabase、tunnel、extension、ai、messageQueue、backend和adapterjdbcAgent、native、plugin、http、legacy等可选driver例如 DuckDB 路径中为duckdb。它不参与错误分类、恢复或重试决策。diagnostics白名单化的诊断字段。sqlState最多 32 个可打印 ASCII 字符、vendorCode、exceptionClass最多 128 字符diagnostics.adapterCode是适配器协议提供的可选出错码例如 DuckDB worker 的duckdb_execute_failed、duckdb_worker_poisoned仅用于诊断展示不替代稳定的 DBXcode。errorPosition适配器提供的可选出错位置目前只有原生 PostgreSQL 驱动填充。line/column为 1-based、按 Unicode 码点计数offset为语句内 0-based 码点下标均相对实际下发的语句文本。它不参与分类、重试或恢复客户端只有在能证明该语句仍映射回当前编辑器内容时才用它定位否则忽略。位置以可解析后缀在db层内部传递在query.rs还原为类型化字段该后缀不会出现在detail或任何用户可见文本中。operationOutcome只能是not_started或unknown。结果未知时不能自动重放用户操作。messageParams只能包含 catalog 声明的 string、number、boolean 标量对应 Rust 的BackendMessageParam::String/Integer/Boolean不得携带 SQL、URL、凭据或任意对象。构造器内有debug_assert校验参数个数与类型合法性。字段私有性Rust 字段保持私有新增错误必须通过 catalog 构造避免 code、key 和参数声明漂移。错误码 catalog 全表文档给出的 catalog 与源码 backend_error.rs 中的条目完全一致code含义DBX-JDBC-1001连接建立失败DBX-JDBC-1002已建立连接中断DBX-JDBC-2001操作超时且尚未开始DBX-JDBC-2002操作超时但结果未知DBX-JDBC-2003操作取消DBX-JDBC-3001资源繁忙操作尚未开始DBX-JDBC-3002Runtime 被替换DBX-JDBC-4001数据库 SQL 执行失败DBX-JDBC-5001Agent 传输或协议失败DBX-JDBC-5002Agent 错误上下文违反契约DBX-JDBC-9001旧 Agent 错误无法可靠分类DBX-LEGACY-0001非 Agent 或未迁移的字符串错误源码中还存在一个文档表格未列出的独立事务错误码DBX-TXN-1001backendErrors.transaction.sessionExpired带timeoutSecs整数参数由from_manual_transaction_session_expired生成用于手动事务会话已过期、DBX 已在执行前回滚的场景。分类映射的源码级细节structured_entry函数把 Agent 的(category, stage, operationOutcome)组合映射到 catalog code见 backend_error.rs几个关键组合规则ConnectionRequest/Checkout/Connect/Validate阶段且NotStarted→DBX-JDBC-1001Execute/Fetch/Cancel/Close阶段且Unknown→DBX-JDBC-1002其余组合 →DBX-JDBC-5002。TimeoutNotStarted→DBX-JDBC-2001Unknown→DBX-JDBC-2002。ResourcesessionDisposition ReplaceRuntime→DBX-JDBC-3002NotStarted→DBX-JDBC-3001否则 →DBX-JDBC-5002。SqlExecute/Fetch/Cancel/Close阶段且Unknown→DBX-JDBC-4001否则 →DBX-JDBC-5002。也就是说非法组合不会得到看起来合理的错误码而是被明确标记为契约违例这是恢复逻辑依赖可验证类型的底层保障。新增错误码的标准流程按文档要求新增错误码需要四步在 backend_error.rs 的 catalog 中增加唯一code、messageKey和参数声明CatalogEntryParamSpec白名单为所有 locale 增加相同 key见 apps/desktop/src/i18n/locales 下的多语言文件并扩展 catalog 完整性测试增加 Rust 映射和序列化测试以及前端 normalize/翻译测试见 backendErrors.spec.ts若错误来自 Agent先在AgentErrorContext中定义可验证的事实和合法组合再添加 catalog 映射不要用错误文本补分类。四、detail 与安全边界detail是数据库/驱动诊断的可选补充不是分类依据。已类型化的 SQL 错误会保留数据库/驱动返回的原始正文未知或连接类错误才走 DBX 的凭据与 Session 清洗兜底。边界规则文档原文要点大小上限最多保留 64 KiB 的 UTF-8 文本源码中MAX_DETAIL_BYTES 64 * 1024超出部分按字符边界截断bounded_text用char_indices保证不截断多字节字符空内容丢弃。换行语义查询层补充上下文时使用独立换行符\n追加不以空格拼接消费者与测试应保留该换行边界。透传与脱敏数据库厂商错误正文ERROR: relation ... does not exist、ORA-00942、约束冲突中的值、驱动返回的 statement 文本原样保留而连接配置和未知错误文本中的 JDBC URL、密码、token、授权头、密钥、Session 标识会被替换或在只剩敏感内容时整个删除。不解析 SQLDBX 不解析、抽取或改写 SQL payload也不会主动把执行 SQL 追加到错误——因此 SQL 方言、嵌套括号、引号和业务字面量不会被错误的通用字符串规则破坏。需要内部诊断时单独记录原始请求不得把内部日志对象直接复用为公共 envelope。内部字段不外泄AgentErrorContext中的agentSessionId、重试标记和内部恢复字段不会作为结构化字段进入公共 envelope非 SQL 类别的驱动错误正文如果含 Session 或凭据文本公共 detail 仍会脱敏。without_detail()只在调用方明确要求隐藏 detail 时移除原文超时和取消没有服务端 detail 时只返回摘要。脱敏实现的源码佐证backend_error.rs 中的脱敏管线清晰可循safe_detail先脱敏再判断是否只剩敏感令牌contains_only_redacted_sensitive_tokens只剩敏感内容时返回Noneredact_sensitive_fragments识别password、token:等敏感键值对sensitive_key_name覆盖 password、passwd、pwd、token、accessToken、refreshToken、secret、authorization、apiKey、credential、auth、key、user、username、uid、accessKey、privateKey、session、sessionId、agentSessionId、jwt、cookie 等值替换为[redacted]bearer/authorization:后的令牌同样处理支持引号包裹与花括号包裹的值、转义字符redact_url_userinfo扫描://后的 authority把user:password中的密码部分替换为[redacted]redact_session_identifier匹配session id、session_id、agentSessionId及session:形式替换随后的值bounded_ascii用于sqlState、exceptionClass、adapterCode等诊断字段仅保留可打印 ASCII 与空格并截断。不同来源的 detail 策略场景codedetail 行为实现入口类型化 SQL 失败DBX-JDBC-4001保留原生正文bounded_native_detail不重写from_sql_detail/from_sql_detail_with_position未知/连接类错误视类型脱敏兜底bounded_detail→safe_detailfrom_agent_call_error的_分支查询超时Rust 执行器生成DBX-JDBC-2002stageexecute保留超时诊断 detailfrom_timeout_detailPostgreSQL 原生ERROR:诊断DBX-JDBC-4001stageexecute保留原始 detail 可选errorPositionfrom_sql_detail_with_position集成验证见 live_postgres_error_position.rsDuckDB worker 错误DBX-JDBC-4001SQL 类或DBX-LEGACY-0001保留Parser Error/Catalog Error等正文worker code 进diagnostics.adapterCodefrom_duckdb_worker_error连接/超时/取消/清理—不使用DBX-JDBC-4001分类—五、传输边界Tauri、HTTP 与多语句查询Tauri Desktop查询命令将QueryExecutionError映射为BackendError。即使通过execute_multi命令执行单语句或事务查询dbx-core也会在整个 multi-query 核心链路中保留QueryExecutionError直到 Tauri 边界才转换为BackendError——不得先降级为字符串再重建 envelope。apps/desktop/src/lib/backend/tauri.ts 在查询失败时抛出BackendErrorException前端因此能同时取得messageKey和原始detail。Tauri 的连接、传输、导入和导出边界也统一将拒绝结果转换为BackendErrorException未知对象只提取有长度上限的message、reason或detail内容为空时使用稳定摘要。HTTP Webcrates/dbx-web 的 multi-query 路由消费 typed 核心入口将AppError序列化为同一套 envelope正常 HTTP 错误响应会保留按规则生成的detail。BackendError::without_detail()仅用于需要主动隐藏详情的兼容场景不是默认响应路径。HTTP status 只表示传输结果不能替代或改变BackendError.code。桌面端 HTTP 失败包括 multipart、SSE、上传、下载和 Nacos 特殊接口必须调用backendResponseError不能直接构造new Error(await response.text())否则会丢失BackendError v1envelope。多语句查询ExecuteMultiResult.error和进度事件中的error是权威的结构化错误字段execution_error表示该结果确实失败。已经进入 typed 通用逐语句路径的错误必须直接从QueryExecutionError生成该字段不能从兼容字符串反向推断。MySQL 和 SQL Server 的专用 batch executor 当前仍是字符串驱动边界只有在驱动层提供可验证的 typed failure facts 后才能迁移旧的Error行仅用于兼容真实查询结果中名为Error的普通列不能被当作失败。六、前端展示规则前端有两个核心函数实现在 apps/desktop/src/i18n/backend-errors.tsnormalizeBackendError只接受完整且类型正确的 envelopedetail如果存在必须是 string兼容 fallback 的单次上限为 64 KiB。解析嵌套的{ error }、{ backendError }、BackendErrorException和跨 realm 的 Error-like 对象时使用有限深度和循环检测无法识别的对象只保留有界的message、reason或detail文本空对象使用稳定摘要。translateBackendError的结构化路径为使用messageKey和messageParams生成当前 locale 的自定义摘要若detail非空且不同于摘要在摘要后追加空行和 detail无法识别的旧字符串继续原样展示或按兼容 pattern 翻译。catch 到异常时必须把原始对象传给翻译器translateBackendError(t, error)不要先执行error.message || String(error)否则会丢失messageKey、参数和服务端 detail。旧版非 i18n 页面可以使用formatError但绝不能把结构化 envelope 直接转换成[object Object]。多语言 key 位于 apps/desktop/src/i18n/locales如 en.ts、zh 等 locale 中的backendErrors.*前端翻译与 normalize 行为由 backendErrors.spec.ts 覆盖。七、协议演进与兼容规则version表示 envelope 版本不表示 Agent Protocol 版本。未知的大版本不能按旧字段强行解析客户端应保留安全 fallback并记录原始版本用于诊断。新增可选字段属于向后兼容变更改变字段类型、必填性、枚举语义、错误码含义或安全边界时必须发布新版本并保留旧版本适配器。客户端应忽略未知的可选字段和未知的source/origin枚举值但仍严格校验version、code、messageKey、messageParams、operationOutcome和detail的基本类型。code是稳定机器标识不能复用messageKey是稳定本地化标识文案可以调整但 key 的语义不能改变。错误码废弃时保留旧 locale 和兼容映射。结构化 envelope 可生成本地化摘要并追加按错误来源处理的detail旧字符串或 malformed object 使用有界文本 fallback空响应只显示稳定摘要不伪造数据库原因。operationOutcomeunknown不能因为 fallback 文本、source、origin 或 detail 被推断为可重试恢复决策只依赖 Rust 中的类型化事实。兼容代码的退役门槛包括不再存在直接读取 HTTP 响应文本并抛错的路径迁移后的后端错误展示调用点不再在translateBackendError前预先提取.message/String(error)在所有消费者接受BackendError v1且线协议测试通过前不移除旧字符串或旧版错误行。八、恢复规则与 RecoveryPolicy 实现恢复规则的核心原则是结果未知不重放operationOutcomeunknown禁止自动重放 SQL、写入、DDL、事务和批处理用户操作即使 Agent 声明可重试也只做 Session/Runtime 恢复并向用户返回原错误只读 metadata只有connection quarantine场景可以新建 Session 重试最多一次replace_runtime移除共享同一 Runtime 的路由最终决定权在 Rust不在 Agent 或前端contract violation、timeout、cancel至少隔离当前 Session旧 Session 的迟到结果不得影响新的路由代际。这些规则在 agent_recovery.rs 中有完全对应的实现。RecoveryScope区分UserOperation、ReadOnlyMetadata { retried }、Keepalive、ConnectionOpenRecoveryDecision为KeepSession、RetryReadOnlyMetadata、QuarantineSession、ReplaceRuntime。RecoveryPolicy::decide的决策表如下错误变体 / 事实决策ContractViolationQuarantineSessionTransportReplaceRuntimeTimeout/CanceledQuarantineSessionStructured且 category 为 Timeout/CanceledQuarantineSessionsessionDisposition ReplaceRuntimeReplaceRuntimesessionDisposition Quarantine且 categoryConnection 且ReadOnlyMetadata{retried:false}RetryReadOnlyMetadata仅此一处允许重试sessionDisposition Quarantine其余QuarantineSessionsessionDisposition Keep或缺失KeepSession注意Keepalive与ConnectionOpen场景同样由类型化决策驱动不因错误文本变化。恢复契约的自动化测试见 agent_recovery_contract.rs。九、提交前检查清单文档为涉及后端错误体系的改动提供了完整的本地验证命令在仓库根目录执行cargo fmt --all -- --check cargo clippy -j 1 -p dbx-core --no-default-features --all-targets -- -D warnings cargo test -j 1 -p dbx-core --no-default-features --lib backend_error::tests cargo test -j 1 -p dbx-core --no-default-features --lib agent_recovery::tests cargo check -j 1 -p dbx-web --no-default-features pnpm typecheck pnpm vitest run apps/desktop/src/i18n/__tests__/backendErrors.spec.ts其中backend_error::tests与agent_recovery::tests分别覆盖 catalog 映射、脱敏边界与恢复决策Rust 侧单测位于 backend_error.rs 与 agent_recovery.rs 的#[cfg(test)]模块前端 vitest 覆盖normalizeBackendError/translateBackendError的解析与翻译路径。十、实践要点速查新错误先定类型事实再定 code来自 Agent 的错误先在AgentErrorContext中定义合法的 category/stage/outcome/disposition 组合非法组合自动落到DBX-JDBC-5002。分类只发生在 Rust任何query/schema/connection/keepalive/UI 代码都不做文本分类字符串只有经try_agent_error_from_legacy证明来源后才恢复为 Agent 错误。detail 双轨制类型化 SQL 错误原样保留厂商正文最多 64 KiB、按字符边界截断未知与连接类错误走凭据/Session 脱敏脱敏后只剩敏感令牌则整体丢弃。前端必须传原始 error 对象translateBackendError(t, error)禁止先行error.message || String(error)HTTP 失败统一走backendResponseError。operationOutcomeunknown永不重放恢复决策只看 Rust 类型化事实唯一允许的重试路径是只读 metadata 的connection quarantine且最多一次。version与code是永久契约新增可选字段可保持 v1改类型、必填性、语义或安全边界必须升版本并保留旧适配器错误码只能废弃不能复用。【免费下载链接】dbx15MB轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lightweight, cross-platform database client. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server and more.项目地址: https://gitcode.com/t8y2/dbx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号