跳到主要内容

退出码

CLI 用结构化退出码表示执行结果。脚本靠它分支,CI 靠它判断流水线是否中断。

退出码定义​

退出码常量语义典型触发
0SUCCESS成功命令正常完成
1ERROR通用错误(兜底)没有命中任何语义分类的错误
2AUTH_FAILED认证失败未登录、Token 过期、无权限
3INVALID_INPUT参数或输入校验失败缺必填参数、枚举值非法、格式错误、非交互环境缺 envId、命令与环境模式不匹配
4NOT_FOUND资源不存在函数名或环境 ID 无效、集合不存在、文件或对象不存在
5API_ERROR云 API 或网络错误CloudBase API 报错、请求超时、触发限频、SDK 异常
6FILE_ERROR本地文件或配置错误cloudbaserc.json 缺失或损坏、路径不存在、文件读写失败、依赖未安装

退出码怎么判定​

退出码挂在错误对象上,按下面的顺序取值,命中即停:

顺序依据例子
1错误自带的 exitCode命令里显式指定的退出语义
2CLI 本地错误码精确匹配TOKEN_EXPIRED → 2、FUNCTION_NOT_FOUND → 4、INVALID_CONFIG → 6
3云 API 错误码的基段FailedOperation.PGExecuteSqlError → FailedOperation → 5
4manager-node 自定义错误码前缀PREFLIGHT_* → 6、CLOUD_* → 5、BUILD_* → 3
5兜底1

想知道某个报错会退几,看 --json 输出里的 error.code:本地码查表,云 API 码看第一个 . 之前的基段,manager-node 码看前缀。

在脚本中分支​

tcb fn deploy app -e my-env-id
case $? in
0) echo "部署成功" ;;
2) echo "认证失败"; tcb login ;;
5) echo "云 API 错误,5 秒后重试"; sleep 5; tcb fn deploy app -e my-env-id ;;
*) echo "失败,退出码 $?"; exit 1 ;;
esac

5 是唯一适合自动重试的退出码,其余重试只是浪费时间:

for i in 1 2 3; do
tcb fn deploy app -e my-env-id && exit 0
[ $? -eq 5 ] || exit $?
sleep 5
done
exit 1

在 CI 中​

CI 默认把非 0 退出码当作失败并中断步骤,一般不需要额外处理。要按退出码分支,就在 shell 里读 $?:

- name: Deploy function
env:
ENV_ID: ${{ secrets.ENV_ID }}
run: |
tcb fn deploy app --env-id "$ENV_ID" --json --yes
code=$?
if [ $code -eq 5 ]; then
sleep 5
tcb fn deploy app --env-id "$ENV_ID" --json --yes
exit $?
fi
exit $code

steps.<id>.outcome 只会给出 success / failure,拿不到具体退出码。

JSON 错误对象​

加 --json 时,失败结果输出到 stdout:

{
"error": {
"code": "FUNCTION_NOT_FOUND",
"message": "函数 app 不存在",
"exit_code": 4,
"solution": "检查函数名,或运行 tcb fn list 查看现有函数",
"docs": "https://docs.cloudbase.net/cli-v1/functions/list",
"requestId": "1a2b3c4d-0000-0000-0000-000000000000"
}
}
  • code:错误码,退出码的判定依据
  • exit_code:进程退出码,与 $? 一致
  • solution / docs / requestId:错误自带时才有

说明​

  • 退出码不是 HTTP 状态码:4 表示资源不存在,不是 404;5 表示云 API 错误,不是 500
  • --yes 只跳过确认提示,不改变执行结果和退出码
  • 多条命令串联时用 && 或 set -e,避免前一条失败后继续执行
  • 需要定位具体报错时加 --verbose,会打印错误栈和 API 请求参数