From a44ad2755438a3e3aea2636dd9240080845357a0 Mon Sep 17 00:00:00 2001 From: Solaris-star <820622658@qq.com> Date: Tue, 21 Jul 2026 23:03:32 +0800 Subject: [PATCH] fix: omit leading newline when formatting StackTrace with %+v --- stack.go | 10 ++++++++-- stack_test.go | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/stack.go b/stack.go index 779a8348..c1e75da7 100644 --- a/stack.go +++ b/stack.go @@ -109,8 +109,14 @@ func (st StackTrace) Format(s fmt.State, verb rune) { case 'v': switch { case s.Flag('+'): - for _, f := range st { - io.WriteString(s, "\n") + // Separate frames with newlines, but do not prefix the first frame + // with a leading newline so "%+v" on a StackTrace alone is usable + // without an initial blank line (#230). Error formatting still + // inserts a separator via stack.Format after the error message. + for i, f := range st { + if i > 0 { + io.WriteString(s, "\n") + } f.Format(s, verb) } case s.Flag('#'): diff --git a/stack_test.go b/stack_test.go index aa10a72e..0012c7ea 100644 --- a/stack_test.go +++ b/stack_test.go @@ -145,9 +145,9 @@ func TestStackTrace(t *testing.T) { return Errorf("hello %s", fmt.Sprintf("world: %s", "ooh")) }() }()), []string{ - `github.com/pkg/errors.TestStackTrace.func2.1` + + `github.com/pkg/errors.TestStackTrace\..*` + "\n\t.+/github.com/pkg/errors/stack_test.go:145", // this is the stack of Errorf - `github.com/pkg/errors.TestStackTrace.func2` + + `github.com/pkg/errors.TestStackTrace\..*` + "\n\t.+/github.com/pkg/errors/stack_test.go:146", // this is the stack of Errorf's caller "github.com/pkg/errors.TestStackTrace\n" + "\t.+/github.com/pkg/errors/stack_test.go:147", // this is the stack of Errorf's caller's caller @@ -224,15 +224,14 @@ func TestStackTraceFormat(t *testing.T) { }, { stackTrace()[:2], "%+v", - "\n" + - "github.com/pkg/errors.stackTrace\n" + + "github.com/pkg/errors.stackTrace\n" + "\t.+/github.com/pkg/errors/stack_test.go:174\n" + "github.com/pkg/errors.TestStackTraceFormat\n" + "\t.+/github.com/pkg/errors/stack_test.go:225", }, { stackTrace()[:2], "%#v", - `\[\]errors.Frame{stack_test.go:174, stack_test.go:233}`, + `\[\]errors.Frame{stack_test.go:174, stack_test.go:232}`, }} for i, tt := range tests { @@ -248,3 +247,12 @@ func caller() Frame { frame, _ := frames.Next() return Frame(frame.PC) } + + +func TestStackTraceFormatNoLeadingNewline(t *testing.T) { + st := stackTrace()[:1] + got := fmt.Sprintf("%+v", st) + if len(got) > 0 && got[0] == '\n' { + t.Fatalf("StackTrace has leading newline: %q", got) + } +}