Add errors.Errorf

This commit is contained in:
Dan Jones 2024-01-17 10:58:39 -06:00
commit 6e7400df4d
5 changed files with 160 additions and 0 deletions

61
errorf.go Normal file
View file

@ -0,0 +1,61 @@
package errors
import "fmt"
// Returns a ResponsableError formatted from the message, with the specified status.
// Errorf passes the heavy lifting off to fmt.Errorf, and returns a similar error.
// If one error is passed in the format, this will return an UnwrappableError.
// If more than one error is passed in the format, this will return an UnwrappableErrors.
func Errorf(status int, format string, parts ...any) ResponsableError {
err := fmt.Errorf(format, parts...)
msg := err.Error()
er := &erf{status, msg}
if we, ok := err.(wrappedError); ok {
return &wrapErr{er, we.Unwrap()}
}
if wes, ok := err.(wrappedErrors); ok {
return &wrapErrs{er, wes.Unwrap()}
}
return er
}
var _ ResponsableError = new(erf)
type erf struct {
stat int
msg string
}
func (e *erf) Status() int {
return e.stat
}
func (e *erf) Error() string {
return e.msg
}
func (e *erf) Msg() string {
return e.msg
}
var _ UnwrappableError = new(wrapErr)
type wrapErr struct {
*erf
err error
}
func (e *wrapErr) Unwrap() error {
return e.err
}
var _ UnwrappableErrors = new(wrapErrs)
type wrapErrs struct {
*erf
errs []error
}
func (e *wrapErrs) Unwrap() []error {
return e.errs
}

71
errorf_test.go Normal file
View file

@ -0,0 +1,71 @@
package errors
import (
"errors"
"net/http"
"testing"
"github.com/stretchr/testify/suite"
)
func TestErrorf(t *testing.T) {
suite.Run(t, new(ErrorfTestSuite))
}
type ErrorfTestSuite struct {
suite.Suite
}
func (s *ErrorfTestSuite) TestNoWrap() {
var err ResponsableError = Errorf(http.StatusTeapot, "%d is more than %d", 42, 13)
s.Assert().NotNil(err)
_, ok := err.(UnwrappableError)
s.Assert().False(ok)
_, ok = err.(UnwrappableErrors)
s.Assert().False(ok)
exp := "42 is more than 13"
s.Assert().Equal(exp, err.Error())
s.Assert().Equal(exp, err.Msg())
s.Assert().Equal(http.StatusTeapot, err.Status())
}
func (s *ErrorfTestSuite) TestWrapOne() {
var wrapped error = errors.New("Here is my handle.")
var err ResponsableError = Errorf(http.StatusTeapot, "I'm a little teapot. %w", wrapped)
s.Assert().NotNil(err)
we, ok := err.(UnwrappableError)
s.Assert().True(ok)
_, ok = err.(UnwrappableErrors)
s.Assert().False(ok)
exp := "I'm a little teapot. Here is my handle."
s.Assert().Equal(exp, we.Error())
s.Assert().Equal(exp, we.Msg())
s.Assert().Same(wrapped, we.Unwrap())
}
func (s *ErrorfTestSuite) TestWrapTwo() {
var wrappedOne error = errors.New("short and stout")
var wrappedTwo error = errors.New("Here is my handle.")
var err ResponsableError = Errorf(http.StatusTeapot, "I'm a little teapot: %w. %w", wrappedOne, wrappedTwo)
s.Assert().NotNil(err)
_, ok := err.(UnwrappableError)
s.Assert().False(ok)
we, ok := err.(UnwrappableErrors)
s.Assert().True(ok)
exp := "I'm a little teapot: short and stout. Here is my handle."
s.Assert().Equal(exp, we.Error())
s.Assert().Equal(exp, we.Msg())
unwrapped := we.Unwrap()
s.Assert().Len(unwrapped, 2)
s.Assert().Same(wrappedOne, unwrapped[0])
s.Assert().Same(wrappedTwo, unwrapped[1])
}

8
go.mod
View file

@ -1,3 +1,11 @@
module codeberg.org/danjones000/responsable-errors
go 1.21.5
require github.com/stretchr/testify v1.8.4
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

10
go.sum Normal file
View file

@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -27,3 +27,13 @@ type UnwrappableErrors interface {
ResponsableError
Unwrap() []error
}
type wrappedError interface {
Error() string
Unwrap() error
}
type wrappedErrors interface {
Error() string
Unwrap() []error
}