Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added terrors.Verbose() #39

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,26 @@ type Error struct {
// should not expect it to contain information about terrors from other downstream
// processes.
cause error

// verbose is a flag that will cause Error() to return the VerboseString() rather
// than the conventional short message. This is intended for ease of debugging,
// especially in tests, rather than regular use.
verbose bool
}

// Error returns a string message of the error.
// It will contain the code and error message. If there is a causal chain, the
// message from each error in the chain will be added to the output.
// message from each error in the chain will be added to the output. If the
// Error is marked as "verbose", it will also return the Params and stack trace.
func (p *Error) Error() string {
if p.verbose {
return p.VerboseString()
}
return p.ShortString()
}

// ShortString returns the conventional error description usually returned by Error()
func (p *Error) ShortString() string {
if p.cause == nil {
// Not sure if the empty code/message cases actually happen, but to be safe, defer to
// the 'old' error message if there is no cause present (i.e. we're not using
Expand Down Expand Up @@ -131,7 +145,7 @@ func (p *Error) StackString() string {

// VerboseString returns the error message, stack trace and params
func (p *Error) VerboseString() string {
return fmt.Sprintf("%s\nParams: %+v\n%s", p.Error(), p.Params, p.StackString())
return fmt.Sprintf("%s\nParams: %+v\n%s", p.ShortString(), p.Params, p.StackString())
}

// Retryable determines whether the error was caused by an action which can be retried.
Expand Down Expand Up @@ -333,3 +347,30 @@ func Is(err error, code ...string) bool {
return false
}
}

// Verbose returns a shallow copy of the given terrors.Error that returns a "verbose" message for error.Error
// instead of the usual short version. If passed nil or another underlying error type, it will return it
// unchanged. This is useful for instance in tests where you may want to write
//
// require.NoError(t, terrors.Verbose(err))
//
func Verbose(err error) error {
if err == nil {
return nil
}
switch err := err.(type) {
case *Error:
return &Error{
verbose: true,

Code: err.Code,
Message: err.Message,
Params: err.Params,
StackFrames: err.StackFrames,
IsRetryable: err.IsRetryable,
cause: err.cause,
}
default:
return err
}
}
35 changes: 35 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/monzo/terrors/stack"
)
Expand Down Expand Up @@ -481,3 +482,37 @@ func TestRetryable(t *testing.T) {
})
}
}

func TestVerbose(t *testing.T) {
var err, verboseErr error
var terr, verboseTerr *Error

assert.Nil(t, err)
assert.Nil(t, Verbose(err))

err = errors.New("blah")
assert.Same(t, err, Verbose(err))

err = New("test", "Test", map[string]string{"flavour": "banana"})
require.NotNil(t, err)

verboseErr = Verbose(err)

terr = err.(*Error)
require.NotNil(t, terr)

verboseTerr = verboseErr.(*Error)
require.NotNil(t, verboseTerr)

assert.Equal(t, err.Error(), terr.ShortString())

assert.NotSame(t, err, verboseErr)
assert.NotSame(t, terr, verboseTerr)
assert.Equal(t, verboseErr.Error(), terr.VerboseString())
assert.Equal(t, verboseErr.Error(), verboseTerr.VerboseString())

// the errors should be equal except for the verbose flag
verboseTerr.verbose = false
assert.Equal(t, terr, verboseTerr)

}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/golang/protobuf v1.4.2
github.com/stretchr/testify v1.6.1
github.com/stretchr/testify v1.7.0
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down
Loading