Skip to content

Commit

Permalink
Add unwrap error message to callback and utilise in responder
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Medley <[email protected]>
  • Loading branch information
ChrysmOre committed Apr 4, 2022
1 parent 7d55c67 commit 153117c
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 7 deletions.
29 changes: 24 additions & 5 deletions errors/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,36 @@ func StackTrace(err error) []log.EventStackTrace {
}

// ErrorMessage extracts a specified error response to be returned
// to the caller if present, otherwise returns the default error
// string
// to the caller if present, otherwise returns an empty string
func ErrorMessage(err error) string {
var rerr messager
if errors.As(err, &rerr) {
if resp := rerr.Message(); resp != "" {
return resp
return rerr.Message()
}

return ""
}

// UnwrapErrorMessage is a callback function that allows you to extract
// an error message from an error. If the error message returned is an empty
// string, UnwrapErrorMessage will attempt to recursively unwrap the error
// until a non-empty string is returned. If no message is returned it will
// return the original error's error string as default.
func UnwrapErrorMessage(err error) string {
originalErr := err

if msg := ErrorMessage(err); msg != "" {
return msg
}

for errors.Unwrap(err) != nil {
if msg := ErrorMessage(err); msg != "" {
return msg
}
err = errors.Unwrap(err)
}

return err.Error()
return originalErr.Error()
}

// UnwrapStatusCode is a callback function that allows you to extract
Expand Down
83 changes: 83 additions & 0 deletions errors/callback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
type testError struct {
err error
statusCode int
message string
logData map[string]interface{}
}

Expand All @@ -37,6 +38,10 @@ func (e testError) LogData() map[string]interface{} {
return e.logData
}

func (e testError) Message() string {
return e.message
}

func TestUnwrapLogDataHappy(t *testing.T) {

Convey("Given an error with embedded logData", t, func() {
Expand Down Expand Up @@ -237,3 +242,81 @@ func TestUnwrapStatusCodeHappy(t *testing.T) {
})

}

func TestUnwrapErrorMessageHappy(t *testing.T) {

Convey("Given an error with embedded error message", t, func() {
err := &testError{
message: "I am an error message",
}

Convey("When ErrorMessage(err) is called", func() {
status := dperrors.ErrorMessage(err)
expected := "I am an error message"

So(status, ShouldEqual, expected)
})
})

Convey("Given an error chain with embedded error message", t, func() {
err1 := &testError{
err: errors.New("original error"),
message: "I am embedded message",
}

err2 := &testError{
err: fmt.Errorf("err1: %w", err1),
}

err3 := &testError{
err: fmt.Errorf("err2: %w", err2),
}

Convey("When UnwrapErrorMessage(err) is called", func() {
status := dperrors.UnwrapErrorMessage(err3)
expected := "I am embedded message"

So(status, ShouldEqual, expected)
})
})

Convey("Given an error chain with multiple embedded status codes", t, func() {
err1 := &testError{
err: errors.New("original error"),
message: "I am embedded message",
}

err2 := &testError{
err: fmt.Errorf("err1: %w", err1),
message: "I am first embedded message",
}

err3 := &testError{
err: fmt.Errorf("err2: %w", err2),
}

Convey("When UnwrapErrorMessage(err) is called", func() {
status := dperrors.UnwrapErrorMessage(err3)
expected := "I am first embedded message"

Convey("The first valid error message is returned ", func() {
So(status, ShouldEqual, expected)
})
})
})

Convey("Given an error with no embedded error message", t, func() {
err := &testError{
err: errors.New("original error"),
}

Convey("When StatusCode(err) is called", func() {
status := dperrors.UnwrapErrorMessage(err)
expected := "original error"

Convey("The orinal error string is returned ", func() {
So(status, ShouldEqual, expected)
})
})
})
}
4 changes: 2 additions & 2 deletions responder/responder.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func respondError(ctx context.Context, w http.ResponseWriter, status int, err er
status = http.StatusInternalServerError
}

msg := dperrors.ErrorMessage(err)
msg := dperrors.UnwrapErrorMessage(err)
resp := errorResponse{
Errors: []string{msg},
}
Expand Down Expand Up @@ -108,7 +108,7 @@ func (r *Responder) Errors(ctx context.Context, w http.ResponseWriter, status in
StackTrace: dperrors.StackTrace(err),
Data: dperrors.UnwrapLogData(err),
})
errorMsgs = append(errorMsgs, dperrors.ErrorMessage(err))
errorMsgs = append(errorMsgs, dperrors.UnwrapErrorMessage(err))
}

log.Info(ctx, "error responding to HTTP request", log.ERROR, &errorLogs)
Expand Down

0 comments on commit 153117c

Please sign in to comment.