Cloudflare Workers 现在可以通过内置错误监控聚合生产环境中的失败,并把堆栈、日志、链路追踪和应用上下文直接交给编码代理。变化的重点不只是“多了一个错误面板”,而是把发现故障、收集证据、定位代码和创建修复 PR 串成一条更短的路径。
从一条异常变成可处理的问题组
生产环境中的同一个缺陷,往往会产生大量看似不同的错误:请求参数不同、边缘节点不同、调用链不同,甚至堆栈中的行号也会随部署变化。如果每条异常都单独处理,团队很快就会被重复告警淹没。
内置错误监控的价值在于先对生产失败进行分组,再为编码代理提供一组相互关联的证据:
- 异常类型与堆栈,帮助定位可能出错的文件和调用路径;
- 同一问题附近的日志,补充输入参数、分支选择和依赖状态;
- Trace 信息,展示请求在 Worker 与下游服务之间如何流动;
- 应用上下文,帮助代理理解环境、请求和部署版本;
- 聚合后的问题,而不是一批重复事件,减少代理重复分析。
这比只把一句 TypeError 复制到聊天窗口有效得多。编码代理得到的是一次故障的“证据包”,因而更适合继续调查、修改代码,并创建供工程师审查的拉取请求。
不过,错误分组并不等于根因判断。两个堆栈相似的异常可能来自不同数据条件,同一个根因也可能表现为多种错误。因此,代理提出的修复仍应经过测试、代码审查和渐进发布。
先让 Worker 产生可诊断的上下文
监控系统只能使用应用实际暴露出来的信息。与其记录一大段拼接字符串,不如输出字段稳定的结构化日志,并为请求保留关联标识。
下面是一个可以放进现有 Workers 项目的最小 TypeScript 示例。它提供 /divide?a=10&b=2 接口,并在除数为零时生成带上下文的生产错误。
export interface Env {
APP_ENV: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const requestId = request.headers.get("cf-ray") ?? crypto.randomUUID();
if (url.pathname !== "/divide") {
return new Response("Try /divide?a=10&b=2", { status: 404 });
}
const a = Number(url.searchParams.get("a"));
const b = Number(url.searchParams.get("b"));
console.log({
event: "divide.requested",
requestId,
environment: env.APP_ENV,
pathname: url.pathname,
divisor: b
});
try {
if (!Number.isFinite(a) || !Number.isFinite(b)) {
throw new TypeError("a and b must be finite numbers");
}
if (b === 0) {
throw new RangeError("division by zero");
}
return Response.json({ result: a / b, requestId });
} catch (error) {
console.error({
event: "divide.failed",
requestId,
errorName: error instanceof Error ? error.name : "UnknownError",
errorMessage: error instanceof Error ? error.message : String(error)
});
throw error;
}
}
};
在项目配置中启用可观测性。以下使用 wrangler.jsonc;如果项目采用 TOML,请转换为对应配置。具体字段应以项目当前使用的 Wrangler 版本为准。
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "production-error-demo",
"main": "src/index.ts",
"compatibility_date": "2025-01-01",
"vars": {
"APP_ENV": "production"
},
"observability": {
"enabled": true,
"head_sampling_rate": 1
}
}
安装并部署后,可以主动触发一条测试异常:
npm install
npx wrangler deploy
# 将地址替换成部署命令输出的 Worker URL
curl -i "https://production-error-demo.example.workers.dev/divide?a=10&b=0"
这里的 head_sampling_rate: 1 适合短期验证,意味着尽可能完整地采集数据。高流量生产服务通常需要根据成本、数据量和排障需求降低采样率,而不是永久全量采集。
交给代理的,不应只是一个堆栈
当错误监控已经把失败聚合成问题后,可以从对应问题入口将材料发送给编码代理。一个理想的调查任务至少应回答四个问题:
- 哪个部署版本开始出现异常?
- 哪些请求路径、参数形态或下游依赖与异常相关?
- 修复应该改变业务行为,还是只增加输入校验?
- 用什么测试证明问题不会再次出现?
如果代理支持附加指令,可以这样约束任务:
调查这个 Cloudflare Workers 生产错误组。
要求:
- 使用附带的 stack trace、logs、traces 和应用上下文定位根因;
- 不要记录或复制认证头、Cookie、令牌及完整用户数据;
- 先添加一个能够复现故障的测试,再实施最小修复;
- 不要改变无关接口的响应格式;
- 在 PR 描述中写明根因、影响范围、测试结果和回滚方式;
- 如果证据不足,请列出缺失信息,不要猜测业务规则。
这样的约束能防止代理为了“消除异常”而简单吞掉错误。例如,下面这种修改会让监控变安静,却可能把真实故障伪装成成功响应:
try {
return await handleRequest(request);
} catch {
return new Response("OK");
}
更合理的修复应保留明确的失败语义:对可预期的无效输入返回 4xx,对真正的内部错误继续记录并返回 5xx,同时避免向客户端泄露堆栈。
安全边界决定这条链路能否长期使用
把生产上下文发送给代理,也意味着需要认真处理数据访问边界。日志、Trace 和异常对象中可能包含用户标识、查询参数、认证信息或业务数据。
上线前建议检查:
- 日志中不要写入
Authorization、Cookie、API Token 或密码; - 对邮箱、手机号、用户 ID 等字段进行删除、截断或哈希化;
- 只授予代理读取必要仓库、问题上下文和创建分支的权限;
- 禁止代理绕过分支保护直接合并或部署生产环境;
- 为代理创建的 PR 强制执行单元测试、类型检查和安全扫描;
- 在 PR 中保留问题组、部署版本和测试证据之间的关联;
- 对高风险服务采用灰度发布,并观察相同错误组是否继续增长。
尤其要避免把“能创建 PR”误解成“可以自动上线”。代理擅长缩短调查和编码时间,但它无法单独确认业务意图、数据合规要求以及修复对其他调用方的影响。
推荐的落地顺序
可以先选择一个错误量适中、测试较完整的 Worker 试点:启用错误监控,改善结构化日志,验证错误分组质量,再把少量问题发送给代理。衡量效果时,不要只统计生成了多少 PR,更应该观察平均定位时间、重复告警数量、修复后的回归率以及人工审查成本。
一条稳妥的生产链路应当是:监控负责发现和聚合,代理负责整理证据并提出代码修改,CI 负责验证,工程师负责判断和批准。这样既能利用自动化缩短故障处理时间,也不会把生产安全交给一次未经验证的代码生成。