forked from Gitlink/gitlink-cli
69 lines
1.9 KiB
Go
69 lines
1.9 KiB
Go
package common
|
||
|
||
import (
|
||
"errors"
|
||
|
||
"github.com/gitlink-org/gitlink-cli/internal/client"
|
||
clierrors "github.com/gitlink-org/gitlink-cli/internal/errors"
|
||
"github.com/gitlink-org/gitlink-cli/internal/output"
|
||
)
|
||
|
||
// TryPrintError 尝试把 error 转换为 envelope 格式并输出到 stdout。
|
||
// 返回 true 表示已识别并处理;false 表示该 error 类型不被识别,应由调用方走原有路径。
|
||
//
|
||
// 设计意图:让 shortcut 的错误处理路径与 api 命令对齐,
|
||
// 使 `--format json` 输出可被 jq 解析的标准 envelope:
|
||
//
|
||
// {"ok":false, "error":{"code":N, "message":"...", "suggestion":"..."}}
|
||
//
|
||
// 支持的 error 类型:
|
||
// - *client.APIError : HTTP 错误(404/403/401 等),code = HTTP 状态码
|
||
// - *clierrors.CLIError : 业务级错误(输入/认证/网络等),code 由 kind 映射
|
||
//
|
||
// 注:放在 common 包(而非 output 包)以避免与 client 包形成导入循环。
|
||
func TryPrintError(err error, format string) bool {
|
||
if err == nil {
|
||
return false
|
||
}
|
||
|
||
var apiErr *client.APIError
|
||
if errors.As(err, &apiErr) {
|
||
env := output.ErrorEnvelope(apiErr.Code, apiErr.Message, apiErr.Suggestion)
|
||
_ = output.Print(env, format)
|
||
return true
|
||
}
|
||
|
||
var cliErr *clierrors.CLIError
|
||
if errors.As(err, &cliErr) {
|
||
env := output.ErrorEnvelope(kindToCode(cliErr.Kind), cliErr.Message, cliErr.Suggestion)
|
||
_ = output.Print(env, format)
|
||
return true
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
// kindToCode 把 CLIError.Kind 映射到近似的 HTTP 状态码,用于 envelope.error.code 字段
|
||
func kindToCode(kind clierrors.ErrorKind) int {
|
||
switch kind {
|
||
case clierrors.KindAuth:
|
||
return 401
|
||
case clierrors.KindInput:
|
||
return 400
|
||
case clierrors.KindNotFound:
|
||
return 404
|
||
case clierrors.KindForbidden:
|
||
return 403
|
||
case clierrors.KindNetwork:
|
||
return 503
|
||
case clierrors.KindServer:
|
||
return 500
|
||
case clierrors.KindConfig:
|
||
return 500
|
||
case clierrors.KindGit:
|
||
return 500
|
||
default:
|
||
return 500
|
||
}
|
||
}
|