79 lines
2.8 KiB
Go
79 lines
2.8 KiB
Go
package oci
|
||
|
||
import (
|
||
"errors"
|
||
"regexp"
|
||
"strings"
|
||
|
||
"github.com/oracle/oci-go-sdk/v65/common"
|
||
)
|
||
|
||
// ociErrorHints 把常见 OCI 错误码翻译成给用户看的中文提示。
|
||
var ociErrorHints = map[string]string{
|
||
"IncorrectState": "资源当前状态不允许该操作,通常是仍被其他资源占用或正在变更中",
|
||
"NotAuthorizedOrNotFound": "无权限或资源不存在(可能已被删除)",
|
||
"LimitExceeded": "已达到服务配额上限",
|
||
"QuotaExceeded": "compartment 配额不足",
|
||
"OutOfHostCapacity": "该可用域容量不足,可稍后重试或改用抢机任务",
|
||
"TooManyRequests": "请求过于频繁,请稍后再试",
|
||
"InvalidParameter": "请求参数无效",
|
||
"InternalError": "OCI 服务内部错误,请稍后重试",
|
||
"Conflict": "资源正在变更中,请稍后重试",
|
||
}
|
||
|
||
// ocidRe 匹配消息中的完整 OCID(unique 段 20 位以上才压缩,避免误伤短标识)。
|
||
var ocidRe = regexp.MustCompile(`ocid1\.([a-z0-9]+)\.[a-z0-9]*\.[a-z0-9-]*\.{1,2}[a-z0-9]{20,}`)
|
||
|
||
// shortenOcids 把消息里的长 OCID 压缩为「ocid1.<类型>…<尾6位>」,
|
||
// 保留资源类型与可比对的尾部,避免整条错误被 OCID 撑爆。
|
||
func shortenOcids(s string) string {
|
||
return ocidRe.ReplaceAllStringFunc(s, func(m string) string {
|
||
i := strings.Index(m, ".")
|
||
typ := m[i+1:]
|
||
if j := strings.Index(typ, "."); j > 0 {
|
||
typ = typ[:j]
|
||
}
|
||
return "ocid1." + typ + "…" + m[len(m)-6:]
|
||
})
|
||
}
|
||
|
||
// CompactError 把含 OCI ServiceError 的错误链提炼成短消息:
|
||
// 操作前缀 + 服务端消息,剥掉 SDK 附加的错误码、排障链接、
|
||
// 时间戳、SDK 版本等长文(错误码另经 API 的 ociCode 字段透出);
|
||
// 消息中的长 OCID 压缩为类型加尾位的短形式。非 OCI 错误原样返回。
|
||
func CompactError(err error) string {
|
||
var svcErr common.ServiceError
|
||
if !errors.As(err, &svcErr) {
|
||
return shortenOcids(err.Error())
|
||
}
|
||
prefix := err.Error()
|
||
if i := strings.Index(prefix, ": Error returned by"); i > 0 {
|
||
prefix = prefix[:i] + ": "
|
||
} else {
|
||
prefix = ""
|
||
}
|
||
return shortenOcids(prefix + svcErr.GetMessage())
|
||
}
|
||
|
||
// ErrorHint 返回常见 OCI 错误的中文提示;未识别返回空串。
|
||
// 容量不足常以 code=InternalError 返回,按消息内容归到容量提示。
|
||
func ErrorHint(err error) string {
|
||
var svcErr common.ServiceError
|
||
if !errors.As(err, &svcErr) {
|
||
return ""
|
||
}
|
||
if strings.Contains(svcErr.GetMessage(), "Out of host capacity") {
|
||
return ociErrorHints["OutOfHostCapacity"]
|
||
}
|
||
return ociErrorHints[svcErr.GetCode()]
|
||
}
|
||
|
||
// ServiceStatus 返回错误链中 OCI ServiceError 的 HTTP 状态码;非服务端错误 ok=false。
|
||
func ServiceStatus(err error) (int, bool) {
|
||
var svcErr common.ServiceError
|
||
if errors.As(err, &svcErr) {
|
||
return svcErr.GetHTTPStatusCode(), true
|
||
}
|
||
return 0, false
|
||
}
|