github.com/mailgun/holster/v4@v4.20.0/errors/with_context_test.go (about) 1 package errors_test 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "strings" 8 "testing" 9 10 linq "github.com/ahmetb/go-linq" 11 "github.com/mailgun/holster/v4/callstack" 12 "github.com/mailgun/holster/v4/errors" 13 "github.com/stretchr/testify/assert" 14 15 stderrors "errors" 16 ) 17 18 type TestError struct { 19 Msg string 20 } 21 22 func (err *TestError) Error() string { 23 return err.Msg 24 } 25 26 func TestContext(t *testing.T) { 27 // Wrap an error with context 28 err := &TestError{Msg: "query error"} 29 wrap := errors.WithContext{"key1": "value1"}.Wrap(err, "message") 30 assert.NotNil(t, wrap) 31 32 // Extract as normal map 33 errMap := errors.ToMap(wrap) 34 assert.NotNil(t, errMap) 35 assert.Equal(t, "value1", errMap["key1"]) 36 37 // Also implements the causer interface 38 err = errors.Cause(wrap).(*TestError) 39 assert.Equal(t, "query error", err.Msg) 40 41 out := wrap.Error() 42 assert.Equal(t, "message: query error", out) 43 44 // Should output the message, fields and trace 45 out = fmt.Sprintf("%+v", wrap) 46 assert.True(t, strings.Contains(out, `message: query error (`)) 47 assert.True(t, strings.Contains(out, `key1=value1`)) 48 } 49 50 func TestWithStack(t *testing.T) { 51 err := errors.WithStack(io.EOF) 52 53 var files []string 54 var funcs []string 55 if cast, ok := err.(callstack.HasStackTrace); ok { 56 for _, frame := range cast.StackTrace() { 57 files = append(files, fmt.Sprintf("%s", frame)) 58 funcs = append(funcs, fmt.Sprintf("%n", frame)) 59 } 60 } 61 assert.True(t, linq.From(files).Contains("with_context_test.go")) 62 assert.True(t, linq.From(funcs).Contains("TestWithStack"), funcs) 63 } 64 65 func TestWrapfNil(t *testing.T) { 66 got := errors.WithContext{"some": "context"}.Wrapf(nil, "no error") 67 assert.Nil(t, got) 68 } 69 70 func TestWrapNil(t *testing.T) { 71 got := errors.WithContext{"some": "context"}.Wrap(nil, "no error") 72 assert.Nil(t, got) 73 } 74 75 func TestUnwrap(t *testing.T) { 76 holsterWrappedErr := errors.WithContext{"some": "context"}.Wrap(context.Canceled, "external timeout") 77 assert.True(t, stderrors.Is(holsterWrappedErr, context.Canceled)) 78 79 stdWrappedErr := fmt.Errorf("%w external timeout", context.Canceled) 80 assert.True(t, stderrors.Is(stdWrappedErr, context.Canceled)) 81 }