influxdb/pkg/flux/internal/errors/errors.go

93 lines
2.0 KiB
Go

package errors
import (
"fmt"
"strings"
"github.com/influxdata/flux/codes"
)
// Error is the error struct of flux.
type Error struct {
// Code is the code of the error as defined in the codes package.
// This describes the type and category of the error. It is required.
Code codes.Code
// Msg contains a human-readable description and additional information
// about the error itself. This is optional.
Msg string
// Err contains the error that was the cause of this error.
// This is optional.
Err error
}
// Error implement the error interface by outputting the Code and Err.
func (e *Error) Error() string {
if e.Msg != "" && e.Err != nil {
var b strings.Builder
b.WriteString(e.Msg)
b.WriteString(": ")
b.WriteString(e.Err.Error())
return b.String()
} else if e.Msg != "" {
return e.Msg
} else if e.Err != nil {
return e.Err.Error()
}
return e.Code.String()
}
// Unwrap will return the wrapped error.
func (e *Error) Unwrap() error {
return e.Err
}
func New(code codes.Code, msg ...interface{}) error {
return Wrap(nil, code, msg...)
}
func Newf(code codes.Code, fmtStr string, args ...interface{}) error {
return Wrapf(nil, code, fmtStr, args...)
}
func Wrap(err error, code codes.Code, msg ...interface{}) error {
var s string
if len(msg) > 0 {
s = fmt.Sprint(msg...)
}
return &Error{
Code: code,
Msg: s,
Err: err,
}
}
func Wrapf(err error, code codes.Code, format string, a ...interface{}) error {
return &Error{
Code: code,
Msg: fmt.Sprintf(format, a...),
Err: err,
}
}
// Code returns the error code for the given error.
// If the error is not a flux.Error, this will return
// Unknown for the code. If the error is a flux.Error
// and its code is Inherit, then this will return the
// wrapped error's code.
func Code(err error) codes.Code {
for {
if ferr, ok := err.(*Error); ok {
if ferr.Code != codes.Inherit {
return ferr.Code
} else if ferr.Err == nil {
return codes.Unknown
}
err = ferr.Err
} else {
return codes.Unknown
}
}
}