mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-30 02:00:19 +00:00
153 lines
3.9 KiB
Go
153 lines
3.9 KiB
Go
|
package merry
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
v2 "github.com/ansel1/merry/v2"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
// Error extends the standard golang `error` interface with functions
|
||
|
// for attachment additional data to the error
|
||
|
type Error interface {
|
||
|
error
|
||
|
Appendf(format string, args ...interface{}) Error
|
||
|
Append(msg string) Error
|
||
|
Prepend(msg string) Error
|
||
|
Prependf(format string, args ...interface{}) Error
|
||
|
WithMessage(msg string) Error
|
||
|
WithMessagef(format string, args ...interface{}) Error
|
||
|
WithUserMessage(msg string) Error
|
||
|
WithUserMessagef(format string, args ...interface{}) Error
|
||
|
WithValue(key, value interface{}) Error
|
||
|
Here() Error
|
||
|
WithStackSkipping(skip int) Error
|
||
|
WithHTTPCode(code int) Error
|
||
|
WithCause(err error) Error
|
||
|
Cause() error
|
||
|
fmt.Formatter
|
||
|
}
|
||
|
|
||
|
// make sure errImpl implements Error
|
||
|
var _ Error = (*errImpl)(nil)
|
||
|
|
||
|
// WithValue is equivalent to WithValue(e, key, value).
|
||
|
func (e *errImpl) WithValue(key, value interface{}) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithValue(key, value))
|
||
|
}
|
||
|
|
||
|
// Here is equivalent to Here(e).
|
||
|
func (e *errImpl) Here() Error {
|
||
|
return HereSkipping(e, 1)
|
||
|
}
|
||
|
|
||
|
// WithStackSkipping is equivalent to HereSkipping(e, i).
|
||
|
func (e *errImpl) WithStackSkipping(skip int) Error {
|
||
|
return HereSkipping(e, skip+1)
|
||
|
}
|
||
|
|
||
|
// WithHTTPCode is equivalent to WithHTTPCode(e, code).
|
||
|
func (e *errImpl) WithHTTPCode(code int) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithHTTPCode(code))
|
||
|
}
|
||
|
|
||
|
// WithMessage is equivalent to WithMessage(e, msg).
|
||
|
func (e *errImpl) WithMessage(msg string) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithMessage(msg))
|
||
|
}
|
||
|
|
||
|
// WithMessagef is equivalent to WithMessagef(e, format, args...).
|
||
|
func (e *errImpl) WithMessagef(format string, args ...interface{}) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithMessagef(format, args...))
|
||
|
}
|
||
|
|
||
|
// WithUserMessage is equivalent to WithUserMessage(e, msg).
|
||
|
func (e *errImpl) WithUserMessage(msg string) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithUserMessage(msg))
|
||
|
}
|
||
|
|
||
|
// WithUserMessagef is equivalent to WithUserMessagef(e, format, args...).
|
||
|
func (e *errImpl) WithUserMessagef(format string, args ...interface{}) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithUserMessagef(format, args...))
|
||
|
}
|
||
|
|
||
|
// Append is equivalent to Append(err, msg).
|
||
|
func (e *errImpl) Append(msg string) Error {
|
||
|
return WrapSkipping(e, 1, v2.AppendMessage(msg))
|
||
|
}
|
||
|
|
||
|
// Appendf is equivalent to Appendf(err, format, msg).
|
||
|
func (e *errImpl) Appendf(format string, args ...interface{}) Error {
|
||
|
return WrapSkipping(e, 1, v2.AppendMessagef(format, args...))
|
||
|
}
|
||
|
|
||
|
// Prepend is equivalent to Prepend(err, msg).
|
||
|
func (e *errImpl) Prepend(msg string) Error {
|
||
|
return WrapSkipping(e, 1, v2.PrependMessage(msg))
|
||
|
}
|
||
|
|
||
|
// Prependf is equivalent to Prependf(err, format, args...).
|
||
|
func (e *errImpl) Prependf(format string, args ...interface{}) Error {
|
||
|
return WrapSkipping(e, 1, v2.PrependMessagef(format, args...))
|
||
|
}
|
||
|
|
||
|
// WithCause is equivalent to WithCause(e, err).
|
||
|
func (e *errImpl) WithCause(err error) Error {
|
||
|
return WrapSkipping(e, 1, v2.WithCause(err))
|
||
|
}
|
||
|
|
||
|
// errImpl coerces an error to an Error
|
||
|
type errImpl struct {
|
||
|
err error
|
||
|
}
|
||
|
|
||
|
func coerce(err error) Error {
|
||
|
if err == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if e, ok := err.(Error); ok {
|
||
|
return e
|
||
|
}
|
||
|
|
||
|
return &errImpl{err}
|
||
|
}
|
||
|
|
||
|
// Format implements fmt.Formatter.
|
||
|
func (e *errImpl) Format(s fmt.State, verb rune) {
|
||
|
// the inner err should always be an err produced
|
||
|
// by v2
|
||
|
if f, ok := e.err.(fmt.Formatter); ok {
|
||
|
f.Format(s, verb)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// should never happen, but fall back on something
|
||
|
switch verb {
|
||
|
case 'v':
|
||
|
if s.Flag('+') {
|
||
|
_, _ = io.WriteString(s, Details(e))
|
||
|
return
|
||
|
}
|
||
|
fallthrough
|
||
|
case 's':
|
||
|
_, _ = io.WriteString(s, e.Error())
|
||
|
case 'q':
|
||
|
_, _ = fmt.Fprintf(s, "%q", e.Error())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Error implements the error interface.
|
||
|
func (e *errImpl) Error() string {
|
||
|
return e.err.Error()
|
||
|
}
|
||
|
|
||
|
// Unwrap returns the next wrapped error.
|
||
|
func (e *errImpl) Unwrap() error {
|
||
|
return e.err
|
||
|
}
|
||
|
|
||
|
// Cause implements Error.
|
||
|
func (e *errImpl) Cause() error {
|
||
|
return Cause(e.err)
|
||
|
}
|