问题现象

用户连续发起三次关闭网点的审批,审批都通过了,但网点始终关不掉、状态一直停在待运营,页面还提示异常。反复重试依然失败。同一时段还有大量其他网点报同一个错。

背景

关闭网点必须先走一份终止协议的电子签流程,协议签署生效后才会触发真正的关闭。系统在审批通过后会去第三方电子签平台按模板创建这份终止协议。

根本原因

关闭动作依赖协议签署生效这个前置条件。系统调用第三方按模板创建终止协议时,第三方每次都返回正文必填信息为空的校验错误,即模板里有个必填字段没传或没填。创建失败后,代码直接把这条协议记录作废了:既没有合同号、也从未签署生效,网点关闭的后续逻辑因此永远不触发,状态卡在待运营。而这个失败被静默处理,不提示用户、不告警,用户无从知道卡在哪,只能一遍遍重试,每次都撞在同一个模板校验上。

解决方案

两处一起改。一是提交前先按模板的必填清单校验,缺字段就直接拦住并告诉用户缺什么,别等第三方拒绝;二是第三方创建失败时,把记录标成创建失败可重试而不是静默作废,带上第三方返回的原因,并按错误码聚合告警。

// 提交前校验必填字段,缺什么直接告诉用户
List<String> missing = templateValidator.checkRequired(node, TEMPLATE_ID);
if (!missing.isEmpty()) {
    throw new BizException("协议创建所需信息不完整,缺少:" + missing);
}
Result r = eSignApi.create(node, TEMPLATE_ID);
if (!r.isSuccess()) {
    record.setStatus(CREATE_FAILED);          // 失败态可重试,不作废
    record.setFailReason(r.getErrorMsg());
    metrics.increment("contract.create.fail:" + r.getErrorCode()); // 同码聚合告警
    alert("终止协议创建失败,网点关闭受阻", node.getId(), r.getErrorMsg());
    throw new BizException("协议创建失败:" + r.getErrorMsg());
}

测试建议

构造第三方创建协议失败的分支,断言流程停在明确的失败态、并给出可读原因,而不是回到初始态诱导用户反复重试。对接第三方模板时,用例要覆盖必填字段缺失场景,验证提交前就被拦下。监控侧要验证同一错误码短时间大量出现能触发聚合告警,这类系统性问题往往一报一大片。

经验总结

关键流程的前置步骤失败,必须把卡点显式告知用户并告警,别静默作废让人反复重试;对接第三方模板前,先把必填字段清单和自己实际传的字段对齐。