✨ Add errors.Errorf
This commit is contained in:
parent
59b2969d77
commit
6e7400df4d
5 changed files with 160 additions and 0 deletions
61
errorf.go
Normal file
61
errorf.go
Normal 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
71
errorf_test.go
Normal 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
8
go.mod
|
|
@ -1,3 +1,11 @@
|
||||||
module codeberg.org/danjones000/responsable-errors
|
module codeberg.org/danjones000/responsable-errors
|
||||||
|
|
||||||
go 1.21.5
|
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
10
go.sum
Normal 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=
|
||||||
10
interface.go
10
interface.go
|
|
@ -27,3 +27,13 @@ type UnwrappableErrors interface {
|
||||||
ResponsableError
|
ResponsableError
|
||||||
Unwrap() []error
|
Unwrap() []error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type wrappedError interface {
|
||||||
|
Error() string
|
||||||
|
Unwrap() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type wrappedErrors interface {
|
||||||
|
Error() string
|
||||||
|
Unwrap() []error
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue