// parseConfig returns a parsed configuration for an Azure cloudprovider config file funcparseConfig(configReader io.Reader) (*Config, error) { var config Config
// The resource group name may be in different cases from different Azure APIs, hence it is converted to lower here. // See more context at https://github.com/kubernetes/kubernetes/issues/71994. config.ResourceGroup = strings.ToLower(config.ResourceGroup) return &config, nil }
// NewAlreadyExistsError returns a new instance of AlreadyExists error. funcNewAlreadyExistsError(operationName string)error { return alreadyExistsError{operationName} }
// IsAlreadyExists returns true if an error returned from // NestedPendingOperations indicates a new operation can not be started because // an operation with the same operation name is already executing. funcIsAlreadyExists(err error)bool { switch err.(type) { case alreadyExistsError: returntrue default: returnfalse } }
type alreadyExistsError struct { operationName string }
var _ error = alreadyExistsError{}
func(err alreadyExistsError) Error() string { return fmt.Sprintf( "Failed to create operation with name %q. An operation with that name is already executing.", err.operationName) }
还可以延伸出更复杂一些的树形error体系:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// package net
type Error interface { error Timeout() bool// Is the error a timeout? Temporary() bool// Is the error temporary? }
type UnknownNetworkError string
func(e UnknownNetworkError) Error() string
func(e UnknownNetworkError) Temporary() bool
func(e UnknownNetworkError) Timeout() bool
Error Wrapping
error类型仅包含一个字符串类型的信息,如果函数的调用栈信息为A -> B -> C,如果函数C返回err,在函数A处打印err信息,那么很难判断出err的真正出错位置,不利于快速定位问题。我们期望的效果是在函数A出打印err,能够精确的找到err的源头。