概述
Kubernetes的error是struct error路线,只不过外面包了一个interface StatusError,然后还依赖了1.13的errors.As 特性,把error断言为StatusError。
细节
StatusError
代码位于 staging/src/k8s.io/apimachinery/pkg/api/errors
type APIStatus interface {
Status() metav1.Status
}
type StatusError struct {
ErrStatus metav1.Status
}
func IsNotFound(err error) bool {
reason, code := reasonAndCodeForError(err)
if reason == metav1.StatusReasonNotFound {
return true
}
if _, ok := knownReasons[reason]; !ok && code == http.StatusNotFound {
return true
}
return false
}
func reasonAndCodeForError(err error) (metav1.StatusReason, int32) {
if status := APIStatus(nil); errors.As(err, &status) {
return status.Status().Reason, status.Status().Code
}
return metav1.StatusReasonUnknown, 0
}
func NewNotFound(qualifiedResource schema.GroupResource, name string) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusNotFound,
Reason: metav1.StatusReasonNotFound,
Details: &metav1.StatusDetails{
Group: qualifiedResource.Group,
Kind: qualifiedResource.Resource,
Name: name,
},
Message: fmt.Sprintf("%s %q not found", qualifiedResource.String(), name),
}}
}
可见,Kubernetes的error是struct error路线,只不过外面包了一个interface StatusError,然后还依赖了1.13的errors.As 特性,把error断言为StatusError。
metav1.Status 的这几个字段很重要:
- Code:参考http状态码,判断error类型的2级依据
- Reason:判断error类型的1级依据
- Message:error实际返回的错误信息
AggregateError
有的时候,我们需要一个error数组,而不是单个error,errors包就提供了这种error。
type Aggregate interface {
error
Errors() []error
Is(error) bool
}
func NewAggregate(errlist []error) Aggregate {
// ...
}
它具有message去重能力,error()的返回是所有error的message。还有errors.Is的封装,除此之外,不提供更多方法了。