diff --git a/format/format.go b/format/format.go index 1a2ed877a..3034c1a54 100644 --- a/format/format.go +++ b/format/format.go @@ -52,7 +52,7 @@ var CharactersAroundMismatchToInclude uint = 5 var contextType = reflect.TypeOf((*context.Context)(nil)).Elem() var timeType = reflect.TypeOf(time.Time{}) -//The default indentation string emitted by the format package +// The default indentation string emitted by the format package var Indent = " " var longFormThreshold = 20 @@ -258,7 +258,11 @@ Set PrintContextObjects to true to print the content of objects implementing con func Object(object interface{}, indentation uint) string { indent := strings.Repeat(Indent, int(indentation)) value := reflect.ValueOf(object) - return fmt.Sprintf("%s<%s>: %s", indent, formatType(value), formatValue(value, indentation)) + commonRepresentation := "" + if err, ok := object.(error); ok { + commonRepresentation += "\n" + IndentString(err.Error(), indentation) + } + return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), formatValue(value, indentation), commonRepresentation) } /* diff --git a/format/format_test.go b/format/format_test.go index 4f43d72a9..eb55cee2f 100644 --- a/format/format_test.go +++ b/format/format_test.go @@ -612,6 +612,20 @@ var _ = Describe("Format", func() { Expect(Object(t, 1)).Should(match("time.Time", `2016-10-31T09:57:23.000012345Z`)) }) }) + + Describe("formatting errors", func() { + It("should include the error() representation", func() { + err := fmt.Errorf("whoops: %w", fmt.Errorf("welp: %w", fmt.Errorf("ruh roh"))) + Expect(Object(err, 1)).Should(MatchRegexp(` \<\*fmt\.wrapError \| 0x[0-9a-f]*\>\: \{ + msg\: "whoops\: welp\: ruh roh", + err\: \<\*fmt.wrapError \| 0x[0-9a-f]*\>\{ + msg\: "welp\: ruh roh", + err\: \<\*errors.errorString \| 0x[0-9a-f]*\>\{s\: "ruh roh"\}, + \}, + \} + whoops\: welp\: ruh roh`)) + }) + }) }) Describe("Handling unexported fields in structs", func() { diff --git a/matchers/have_occurred_matcher.go b/matchers/have_occurred_matcher.go index 5bcfdd2ad..22a1b6730 100644 --- a/matchers/have_occurred_matcher.go +++ b/matchers/have_occurred_matcher.go @@ -31,5 +31,5 @@ func (matcher *HaveOccurredMatcher) FailureMessage(actual interface{}) (message } func (matcher *HaveOccurredMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("Unexpected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "occurred") + return fmt.Sprintf("Unexpected error:\n%s\n%s", format.Object(actual, 1), "occurred") } diff --git a/matchers/match_error_matcher_test.go b/matchers/match_error_matcher_test.go index 99ea9acef..7c81d02fa 100644 --- a/matchers/match_error_matcher_test.go +++ b/matchers/match_error_matcher_test.go @@ -135,14 +135,14 @@ var _ = Describe("MatchErrorMatcher", func() { failuresMessages := InterceptGomegaFailures(func() { Expect(errors.New("foo")).To(MatchError("bar")) }) - Expect(failuresMessages[0]).To(ContainSubstring("{s: \"foo\"}\nto match error\n : bar")) + Expect(failuresMessages[0]).To(ContainSubstring("{s: \"foo\"}\n foo\nto match error\n : bar")) }) It("shows negated failure message", func() { failuresMessages := InterceptGomegaFailures(func() { Expect(errors.New("foo")).ToNot(MatchError("foo")) }) - Expect(failuresMessages[0]).To(ContainSubstring("{s: \"foo\"}\nnot to match error\n : foo")) + Expect(failuresMessages[0]).To(ContainSubstring("{s: \"foo\"}\n foo\nnot to match error\n : foo")) }) }) diff --git a/matchers/succeed_matcher.go b/matchers/succeed_matcher.go index da5a39594..327350f7b 100644 --- a/matchers/succeed_matcher.go +++ b/matchers/succeed_matcher.go @@ -34,7 +34,7 @@ func (matcher *SucceedMatcher) FailureMessage(actual interface{}) (message strin if errors.As(actual.(error), &fgErr) { return fgErr.FormattedGomegaError() } - return fmt.Sprintf("Expected success, but got an error:\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1)) + return fmt.Sprintf("Expected success, but got an error:\n%s", format.Object(actual, 1)) } func (matcher *SucceedMatcher) NegatedFailureMessage(actual interface{}) (message string) {