Skip to content

Commit

Permalink
update with only f functions
Browse files Browse the repository at this point in the history
Signed-off-by: Bisakh Mondal <[email protected]>
  • Loading branch information
bisakhmondal committed Apr 15, 2022
1 parent 8aaf350 commit 0c0d413
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 47 deletions.
41 changes: 14 additions & 27 deletions pkg/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,43 +51,25 @@ func (b *base) Format(s fmt.State, verb rune) {
s.Write([]byte(b.Error()))
}

// New returns an error that formats as the given text and a stacktrace with recent
// call frames. Each call to New returns a distinct error value even if the text is
// identical. An alternative to errors.New function.
func New(msg string) error {
return &base{
info: msg,
stack: newStackTrace(),
err: nil,
}
}

// Errorf formats according to a format specifier and returns a new error with
// a stacktrace containing recent call frames. An alternative to fmt.Errorf function.
func Errorf(format string, args ...interface{}) error {
// Newf formats according to a format specifier and returns a new error with a stacktrace
// with recent call frames. Each call to New returns a distinct error value even if the text is
// identical. An alternative of the errors.New function.
//
// If no args have been passed, it is same as `New` function without formatting. Character like
// '%' still has to be escaped in that scenario.
func Newf(format string, args ...interface{}) error {
return &base{
info: fmt.Sprintf(format, args...),
stack: newStackTrace(),
err: nil,
}
}

// Wrap returns a new error with the supplied message as an argument and wrapping another error
// with a stacktrace containing recent call frames.
//
// If cause is nil, this is the same as New.
func Wrap(cause error, msg string) error {
return &base{
info: msg,
stack: newStackTrace(),
err: cause,
}
}

// Wrapf returns a new error by formatting the error message with the supplied format specifier
// and wrapping another error with a stacktrace containing recent call frames.
//
// If cause is nil, this is the same as Errorf.
// If cause is nil, this is the same as fmt.Errorf. If no args have been passed, it is same as `Wrap`
// function without formatting. Character like '%' still has to be escaped in that scenario.
func Wrapf(cause error, format string, args ...interface{}) error {
return &base{
info: fmt.Sprintf(format, args...),
Expand Down Expand Up @@ -133,6 +115,11 @@ func formatErrorChain(err error) string {
return buf.String()
}

// The functions `Is`, `As` & `Unwrap` provides a thin wrapper around the builtin errors
// package in go. Just for sake of completeness and correct autocompletion behaviors from
// IDEs they have been wrapped using functions instead of using variable to reference them
// as first class functions (eg: var Is = errros.Is ).

// Is is a wrapper of built-in errors.Is. It reports whether any error in err's
// chain matches target. The chain consists of err itself followed by the sequence
// of errors obtained by repeatedly calling Unwrap.
Expand Down
39 changes: 19 additions & 20 deletions pkg/errors/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,40 @@ import (
const msg = "test_error_message"
const wrapper = "test_wrapper"

func TestNew(t *testing.T) {
err := New(msg)
func TestNewf(t *testing.T) {
err := Newf(msg)
testutil.Equals(t, err.Error(), msg, "the root error message must match")

reg := regexp.MustCompile(msg + `[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestNew .*\/pkg\/errors\/errors_test\.go:\d+`)
reg := regexp.MustCompile(msg + `[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestNewf .*\/pkg\/errors\/errors_test\.go:\d+`)
testutil.Equals(t, reg.MatchString(fmt.Sprintf("%+v", err)), true, "matching stacktrace in errors.New")
}

func TestErrorf(t *testing.T) {
func TestNewfFormatted(t *testing.T) {
fmtMsg := msg + " key=%v"
expectedMsg := msg + " key=value"

err := Errorf(fmtMsg, "value")
err := Newf(fmtMsg, "value")
testutil.Equals(t, err.Error(), expectedMsg, "the root error message must match")
reg := regexp.MustCompile(expectedMsg + `[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestErrorf .*\/pkg\/errors\/errors_test\.go:\d+`)
reg := regexp.MustCompile(expectedMsg + `[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestNewfFormatted .*\/pkg\/errors\/errors_test\.go:\d+`)
testutil.Equals(t, reg.MatchString(fmt.Sprintf("%+v", err)), true, "matching stacktrace in errors.New with format string")
}

func TestWrap(t *testing.T) {
err := New(msg)
err = Wrap(err, wrapper)
func TestWrapf(t *testing.T) {
err := Newf(msg)
err = Wrapf(err, wrapper)

expectedMsg := wrapper + ": " + msg
testutil.Equals(t, err.Error(), expectedMsg, "the root error message must match")

reg := regexp.MustCompile(`test_wrapper[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestWrap .*\/pkg\/errors\/errors_test\.go:\d+
[[:ascii:]]+test_error_message[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestWrap .*\/pkg\/errors\/errors_test\.go:\d+`)
reg := regexp.MustCompile(`test_wrapper[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestWrapf .*\/pkg\/errors\/errors_test\.go:\d+
[[:ascii:]]+test_error_message[ \n]+> github\.com\/thanos-io\/thanos\/pkg\/errors\.TestWrapf .*\/pkg\/errors\/errors_test\.go:\d+`)

t.Logf("%+v", err)
testutil.Equals(t, reg.MatchString(fmt.Sprintf("%+v", err)), true, "matching stacktrace in errors.Wrap")
}

func TestUnwrap(t *testing.T) {
// test with base error
err := New(msg)
err := Newf(msg)

for i, tc := range []struct {
err error
Expand All @@ -64,11 +63,11 @@ func TestUnwrap(t *testing.T) {
isNil: true,
},
{
err: Wrap(err, wrapper),
err: Wrapf(err, wrapper),
expected: "test_error_message",
},
{
err: Wrap(Wrap(err, wrapper), wrapper),
err: Wrapf(Wrapf(err, wrapper), wrapper),
expected: "test_wrapper: test_error_message",
},
// check primitives errors
Expand All @@ -77,7 +76,7 @@ func TestUnwrap(t *testing.T) {
isNil: true,
},
{
err: Wrap(stderrors.New("std-error"), wrapper),
err: Wrapf(stderrors.New("std-error"), wrapper),
expected: "std-error",
},
{
Expand All @@ -98,7 +97,7 @@ func TestUnwrap(t *testing.T) {

func TestCause(t *testing.T) {
// test with base error that implements interface containing Unwrap method
err := New(msg)
err := Newf(msg)

for i, tc := range []struct {
err error
Expand All @@ -111,11 +110,11 @@ func TestCause(t *testing.T) {
isNil: true,
},
{
err: Wrap(err, wrapper),
err: Wrapf(err, wrapper),
isNil: true,
},
{
err: Wrap(Wrap(err, wrapper), wrapper),
err: Wrapf(Wrapf(err, wrapper), wrapper),
isNil: true,
},
// check primitives errors
Expand All @@ -124,7 +123,7 @@ func TestCause(t *testing.T) {
expected: "std-error",
},
{
err: Wrap(stderrors.New("std-error"), wrapper),
err: Wrapf(stderrors.New("std-error"), wrapper),
expected: "std-error",
},
{
Expand Down

0 comments on commit 0c0d413

Please sign in to comment.