第 11 章 · CLI 产品化与毕业
04 · 错误处理与退出码
明确的退出码、清晰的错误信息、合理的重试建议——让 agent 的错误可诊断。
退出码
CLI 工具通过退出码(exit code)告诉调用方执行结果:
| 退出码 | 含义 | 触发条件 |
|---|---|---|
| 0 | 成功 | agent 正常完成并返回结果 |
| 1 | 启动失败 | 缺少 API key、模型连接失败等 |
| 2 | 执行受限 | 达到迭代上限、任务未完全完成 |
在代码中:
// 启动失败
if (!apiKey) {
console.error("错误: 请设置 OPENAI_API_KEY 环境变量");
process.exit(1);
}
// 执行受限
process.exit(result.stats.hitLimit ? 2 : 0);
// 未捕获异常
main().catch((err) => {
console.error("启动失败:", err);
process.exit(1);
});退出码让脚本可以判断执行结果:
mca ask "修复 bug" --json
if [ $? -eq 2 ]; then
echo "任务未完全完成"
fi错误信息的层次
好的错误信息应该让用户知道三件事:
- 出了什么问题(现象)
- 为什么出问题(原因)
- 怎么解决(建议)
错误: 请设置 OPENAI_API_KEY 环境变量简单但明确——缺少环境变量,设置它就能解决。
MCP 加载失败: JSON 解析错误MCP 配置格式有误,检查 MCP_SERVERS 环境变量的 JSON 格式。
未能完成任务:达到最大迭代次数。任务太复杂,超出了 agent 的处理能力。可以尝试简化任务描述,或拆分为多个子任务。
错误隔离
agent 的多个子系统各自处理自己的错误:
- 模型调用失败。 OpenAI SDK 会抛出异常,被 main 的 catch 捕获。
- 工具执行失败。 工具返回错误字符串(如 "错误:文件不存在"),不抛异常。模型能看到错误并调整策略。
- 权限拒绝。 返回 "操作被拒绝" 作为工具结果,不抛异常。
- Hook 报错。 被捕获并记录到 stderr,不中断主流程。
- MCP 连接失败。 捕获并记录,回退到内置工具。
关键原则:外层错误(启动、连接)用退出码;内层错误(工具、权限)用字符串。
测试错误场景
CLI 参数解析的测试覆盖了正常和异常输入:
- 无参数 → 交互模式
ask无任务 → 交互模式(不崩溃)--json+--no-confirm组合 → 正确解析- 多词任务 → 拼接为完整描述
完整的测试文件在 test/cli.test.ts 中。
登录以继续阅读
解锁完整文档、代码示例及更多高级功能。