AI多Agent协作系统实战(四十五):漏声明了一个变量,整个页面的按钮都死了

服务启停页面,右上角跳出"获取失败"。 三个服务的状态,全部停在"检测中"。 点启动、点停止------没有任何反应

所有按钮集体沉默。原因? 一行代码:var h = s.hermes, o = s.openclaw; ------漏了 w = s.ws

事故现场

给配置中心加了一个新服务:WS(消息网关)。

服务启停页面新增一行:WS(消息网关) [启动] [停止]

刷新页面------右上角绿色横幅变成红色:

复制代码
● 获取失败

三个服务状态全部停在初始值"检测中"。点任何一个"启动"按钮------页面纹丝不动

排查:API 是好的

第一步怀疑后端。直接 curl 服务状态接口:

bash 复制代码
curl http://localhost:8899/api/service-status
json 复制代码
{"ok": true, "status": {"openclaw": false, "hermes": true, "ws": false}}

API 正常------三个服务的状态清清楚楚。

问题在前端。

根因:一个漏声明的变量

打开前端加载服务状态的函数:

javascript 复制代码
function loadSvc(){
  fetch('/api/service-status')
    .then(r => r.json())
    .then(function(d){
      var s = d.services || d.status || {};
      var h = s.hermes, o = s.openclaw;        // ← 问题在这行

      function setRow(tag, svc){
        $(tag).textContent = svc ? '运行中' : '已停止';
      }
      setRow('tagHermes', h);
      setRow('tagOpenclaw', o);
      setRow('tagWs', w);                       // ← w 是什么?!
      $('svcBadge').textContent = '● 服务状态已加载';
    })
    .catch(function(){
      $('svcBadge').textContent = '● 获取失败';  // ← 从这里冒出来
    });
}

新增 WS 服务时,状态读取写的是:

javascript 复制代码
var h = s.hermes, o = s.openclaw;

忘了加上 w = s.ws

于是执行到这一行:

javascript 复制代码
setRow('tagWs', w);     // w 未定义 → ReferenceError: w is not defined

抛异常 → .then 链中断 → 跳到 .catch → "获取失败"。

页面看起来是"获取失败",真相是:一个未声明的变量,中断了整个 Promise 链

为什么"所有按钮没反应"?

按钮的 onclick 是独立的函数(svcAction),按理说不受 loadSvc 影响。

但用户感知的是:点按钮------没有反馈

因为状态加载失败了:

  • 状态标签停在"检测中"(loadSvc 没跑完,没更新)
  • 按钮禁用状态没设置(运行中的服务,启动按钮应该置灰------现在全亮着)
  • 点击后的 toast 提示、状态刷新,全部依赖 loadSvc 的成功回调

一个环节崩了,整个页面的"活着感"都没了。

修复:补上漏掉的变量

javascript 复制代码
var h = s.hermes, o = s.openclaw, w = s.ws;   // ← 补上 w

刷新------状态正常加载,按钮正常工作。

复盘:三个教训

1. "复制模板"式声明,是漏变量的温床。

javascript 复制代码
var h = s.hermes, o = s.openclaw;

这种一行多变量的写法,新增一个服务时,最容易漏掉最后一个

更安全:每个变量单独声明------或者,至少新增功能时,把整行重写一遍,而不是"在结尾加"。

2. .then 链的异常,会被 catch 吞成"假错误"。

vbnet 复制代码
ReferenceError: w is not defined
→ .catch 显示"获取失败"

真正的 bug(w 未定义)被"获取失败"掩盖了。排查时第一反应是"后端挂了"------其实后端好好的。

异常链的 catch 只是兜底,不是诊断------真正的错误要看 console 的 ReferenceError。

3. 新增功能,必须全局搜索旧代码。

加一个 WS 服务,要改的不只是 HTML 那一行:

csharp 复制代码
✅ 状态读取: var w = s.ws
✅ 状态渲染: setRow('tagWs', w)
✅ 按钮禁用: btnStartWs / btnStopWs
✅ 运行计数: 3个服务

漏了任何一个,页面就处于"半新半旧"的诡异状态。

新增一个功能,漏改一行代码------ 整个页面为你保持沉默。 而 Promise 链上的异常, 会把真正的 bug,悄悄翻译成一句"获取失败"。


(真实事故记录:配置中心新增 WS 服务,loadSvc 的状态读取漏写 w = s.ws,setRow 引用未定义变量 → ReferenceError 中断 Promise 链 → catch 显示"获取失败"→ 状态不加载、按钮无反馈。修复:补上变量声明。教训:一行多变量声明的漏写、catch 掩盖真实异常、新增功能需全局同步。)

相关推荐
NeverSettle_1 小时前
Agent 如何快速调用公司接口?——CLI + Skill 实践与踩坑
前端·javascript·后端
环境栈笔记2 小时前
指纹浏览器怎么用:从 Profile、代理到环境检测的完整上手流程
前端·人工智能·后端·自动化
XuCoder2 小时前
MySQL 索引下推(ICP):为什么能少回几次表?
后端
云边有个稻草人2 小时前
向量数据库不必单独建一座“烟囱”:谈谈金仓KES的融合数据库架构
后端
晚安code2 小时前
TransmittableThreadLocal 线程池上下文传递:捕获重放恢复
后端
JoyT2 小时前
Claude Code 多会话协作:会话间消息与并行开发
后端
IT_陈寒2 小时前
SpringBoot自动配置的坑,把我整不会了
前端·人工智能·后端
赵大仁2 小时前
Human-in-the-loop:前端确认流与后端幂等
前端·后端·ai·agent·人机协作
Rain的Java大神之路2 小时前
如何避免订单重复提交
java·redis·后端·面试·架构·rabbitmq·rocketmq