操作失败与错误边界
普通调用只执行一次 run。结构不声明 accept/exceptions/raises/maxRounds,没有独立异常处理阶段。业务在需要的操作处使用统一 result 接收;没有隐式重试或多轮异常解释器。
错误与异常的既有分界
异常是允许业务接收的失败交付:业务明确选择替代、跳过、有限重试或结束。错误涉及运行契约或必要机制无法成立,由内核保留故障归属和访问限制,不能通过业务结果接收消除。取消按运行控制处理,也不能当作普通业务异常继续执行。
“可选维护”只说明业务是否装载该处理、如何接收允许处理的异常;它不把维护内部的持久错误、必要事实发布错误或窗口错误降级。一个分支可以明确失败结束,并非必须修复至成功。框架也不因后处理失败撤销已经正式成立的回答或其他实体效果。
以下几个维度不能混用:
| 维度 | 说明 | 不能据此推断 |
|---|---|---|
| JavaScript 异常值 | Error、DeclaredException 或其他实际抛出值 | 名称本身不能证明是否可接收、是否发生副作用 |
失败诊断 kind | exception/error 保留已声明异常等诊断分类;普通 Error 也可记录为 error | 不能仅凭 wire kind 决定接收资格,不变更协议以掩盖此区别 |
| 当前交付接收资格 | 内部 receptionAllowed 及真实关系、阶段、父窗口共同约束 | 历史诊断或自行构造的值不授权继续执行 |
| 操作事实 | 资源/实体报告真实版本、结果或提交故障 | 失败不等于未发生,成功接收也不证明可以重做 |
因此,普通 Error 可以在有效的业务操作边界被显式接收;DeclaredException 出现在构造、供给捕获或必要持久端口中,仍不能越过错误保护。已有 kind、错误类和持久格式均保留,不要求作者新增节点级异常声明。
资源/实体负责提供事实和真实端口故障,内核负责归属、传播和访问有效性,业务负责允许范围内的后续选择。决策节点不会自动得到异常:作者需在 result.failed 中明确传递所需信息并调用已登记成员。把错误发到观测或在 JS catch 中读取,只是感知,不代表获得了继续使用正式端点的资格。
一种操作接收结构
const content = await work.children.translate.invoke(text, {
result: {
succeeded: checkTranslation,
failed: (failure) => work.children.backup.invoke(text),
},
});
return content;资源方法与子调用采用相同 delta/result 形状。成功默认返回原引用;失败默认继续交付。业务操作的普通 Error 或 DeclaredException 均可由明确的 failed 接收,不要求在结构上先登记 raises/accepts。ExceptionContract 仍可构造有明确业务含义的异常,但它不是内核捕获资格表。
result 是本次操作的处理规则。成功或失败仅选对应分支,分支抛错不再进入同一 failed。只配置 failed 时,类型包含原成功值与备用值。备用操作要自行登记为成员或资源并受自己的窗口和失败规则约束,不隐式重试。
允许业务处理的失败与机制故障
| 情形 | 处理 |
|---|---|
| 资源方法体抛错或子 run 交付业务失败 | 有明确 failed 时接收;否则继续传播 |
| succeeded/failed/delta 结果转换失败 | 依各自接收/被动输出契约处理,不递归进入同一 failed |
| 创建、捕获、暴露、绑定或访问窗口失败 | 技术故障,不允许业务 fallback 清除 |
| 取消、必要变化捕获、CP 提交、propagate 观测失败 | 保留内核故障归属,不重做已完成工作 |
| isolate 观测消费者失败 | 停用相应消费者,业务事实不回滚 |
捕获或 expose 即使抛出 DeclaredException,也仍然是技术边界故障。资格来自发生故障的真实机制边界,不根据错误名称、文本、cause 或“最近一次异常”猜测。
这里的捕获指供给装配中的 Offer.capture;业务资源可以有名为 capture 的普通 methods 操作,其正文与依据校验仍按普通业务操作处理。方法叫 capture、read 或 save 都不自动决定故障类别。
交互反馈与固定文件凭据在实际持久端口失败时产生 PersistenceError,保留原始 cause。Transcript / Memories / View 同样在调用必要 commit 端口处标记错误与同步返回契约违规;适配器已抛出该类时保留原身份,普通错误作为 cause 保存。该故障不能进入资源或子调用的业务 failed 分支;普通 Provider 失败和文件业务拒绝仍按操作结果处理。标记只包住实际持久端口及同步返回检查,不包住实体的输入校验、固定操作冲突、内存安装或提交后的变化发布,也不因保存失败重发或重写。
这里的前置冲突与持久端口内部拒绝分开:提交前核对出的 MemoryBasis/ViewBasis 过期可作为操作异常;持久端口内部即使因 CAS 拒绝而抛错,也按既有必要端口错误处理。当前端口没有“已证明未提交且允许业务继续”的独立返回契约,不能根据 code、错误文字或本地尚未安装就自行降级。
故障分类不证明提交结果:存储可能已经提交但确认丢失。实体不会安装未确认的变更,也不因此自动重试;是否仍可查询或写入遵守各实体明确契约。例如 Memory 持久异常后拒绝新写入和当前查询,宿主须从权威存储重新载入。持久端口错误、业务拒绝和已提交后的发布故障保持各自含义。
未被明确操作接收处理的正式子调用、资源或机制错误,按所属调用记账。归属后,业务用普通 JavaScript catch 捕获并返回正常值,也不能清除此故障或重新使用正式端点。此约束不阻止任意 JS 在 catch 内执行自己的代码;已落实内容及外部效果不回滚。
普通 ResourceOffer.methods 在操作处提供 result.failed;低层 expose 自行定义端点形状,activity.runSync 不额外添加该参数。Memory.apply 和 View 管理使用后者:普通操作异常可结束本层调用,再由预先配置失败接收的父层处理;受保护的错误不能这样消除。不能因为两者都是资源,就假定每个低层端点都有相同的接收参数。
多实体维护中的失败
假设助手消息已经正式追加,后续维护依次生成提案、写入 Memory、调整 View:每一步只承诺自己的效果,框架不建立跨实体事务。
| 失败位置 | 已成立事实 | 允许的后续 |
|---|---|---|
| 提案子调用的普通模型/内容拒绝 | 原消息保留,Memory 尚未写入 | 作者可在该子调用的 result.failed 明确跳过;默认策略不由内核决定 |
| Memory 目标或版本前检冲突 | 本次提案未落实,其他写入可能已发生 | 可接收的操作异常;是否重新生成由业务明确决定,不能暗换依据 |
| Memory 持久提交失败/端口契约违规 | 本地未安装,外部提交可能未知 | PersistenceError,不进入业务 failed,也不自动重试 |
| Memory 落实后必要发布失败 | 记忆已成立,View 尚未改变 | 保留捕获/严格观察故障,不重复写入 |
| View 来源/成员/版本前检拒绝 | Memory 可能已成立,View 未安装 | 按明确策略接收或传播,不能抹去原效果 |
| View 持久提交失败/端口契约违规 | View 本地未安装,外部提交可能未知 | PersistenceError,不自动补纳入 |
| 取消、窗口失效、CP 或其他必要机制故障 | 所有已成立事实保留 | 依内核归属停止,不交给模型决定窗口有效性 |
跳过失败提案不等于成功提案的空批次:空批次仍可执行实体依据核验。一个 failed 分支只覆盖相应操作,不能隐式覆盖整条维护链。Scene 如果等待维护,维护失败可使最终入口失败,但已经正式成立的消息或记忆不会撤回。后台维护、跨资源补偿与自动重试都需要独立业务契约。
子失败来源和父接收事实
ChildCallFailure 是带准确关系凭据的交付错误,exception/cause 保留原始业务异常。并行子调用即使复用同一个异常对象,也有独立交付凭据,不会串源。原样 catch/rethrow 保留关系;解包或换抛是新的业务传播,不通过扫描关系追认旧来源。直接 catch 不应假设一定拿到原 DeclaredException 实例。
普通 children.invoke(...,{result:{failed}}) 在接收边界核验凭据,将原始错误交给业务 failed 回调;精确 create/run/accept 保持原有显式交付边界。已鉴权的来源不能跨父调用或过期窗口复用。
子 returned failed 与父 reception handled 是两个事实。failed 回调返回备用值不改写子失败,handled 值可成为本层后续依据。正常成功交付经接收记 accepted;接收回调失败另记 reception failed。原始返回和转换后值分别保留,不能用最后显示的文本代替真实事实。
本层流程、输出和恢复
run 可以写明确的有限循环。例如格式接纳拒绝后创建一个新的模型子调用,循环 state 保存原拒绝与尝试次数;网络、取消和技术故障不应自动混入业务备用逻辑。每次尝试是新子调用,不是同一 Invocation 的第二轮执行;正式实体写入仍须避免重复。
生产者的 output.result/output.delta 检查本层交付。消费端 result/delta 处理下层交付,两者不是两个节点级正常/异常阶段。一个候选失败后已有预览可能需要丢弃,输出协议明确表达候选替换,不能把多次候选增量拼成一个回答。
CP 保存父接纳与业务循环进度。Frame v6 保留 handled 事实及必要诊断,恢复不重跑已经成功的 failed 回调;需要编码接收值时在 checkpoint.receptions 登记。新执行拒绝旧 round 2/continuation 镜像,不复活删除的异常解释器。详见 Checkpoint。
观测与历史
Invocation.failure 表达真实最终交付,Context 保存已经成立的语义状态。业务已成功但最终观测失败时,不覆盖成功 Context,也不能把失败交付冒充成功。必要错误结算自身损坏是实现故障,不引入递归补救循环。
当前调用过程只发布 execute 的 start/return/throw;输出完成检查与调用控制可以产生失败事实,但不构成独立过程阶段。failure.phase 的 control 描述故障归属,不等于存在 control 过程。父子接收事实归 relationChanges,新运行不产生独立 receive/handling/control 过程或 continue。历史记录中的这些阶段及轮次保留只读解释,不能驱动当前执行。记录消费者由宿主安装,描述规则不改变业务 IO;关闭观测不执行正文描述。见 记录机制。
未引入通用自动补偿、任意重试、跨进程调度或权限平台。内容保存失败仍使服务按真实存储健康决定后续接纳,不由备用分支重提事务。
通用诊断与调用故障策略
@weiliang0121/capix-diagnostics 独立持有 PersistenceError 和 RuntimeErrorHelper,后者把异常转换为有界的诊断纯值。算法保留原来的循环处理、跨 realm 原生错误识别、大小预算和字段读取行为。RuntimeError 基类及 RuntimeErrorValue/Detail 仍来自 contracts;packages/contracts 不因此引入 Node 依赖。
诊断包不决定取消、异常来源、接收资格或重试。Invocation 在自己的操作故障策略中识别真实 PersistenceError,并拒绝业务 failed 回调掩盖必要持久化失败;同一 code 的普通错误不获得该身份。调用与 Runtime 兼容出口重导同一个类和格式化对象,不建立平行错误层次。