Commit c3b9a723 authored by Ian Lance Taylor's avatar Ian Lance Taylor

fmt: include failing method name in panic message

Fixes #25707

Change-Id: Idfa379db8cc0e105ea68455ec0b4a0dbc1b3f485
Reviewed-on: https://go-review.googlesource.com/c/153827
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: default avatarRob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 9ce38f57
...@@ -1683,18 +1683,18 @@ var panictests = []struct { ...@@ -1683,18 +1683,18 @@ var panictests = []struct {
}{ }{
// String // String
{"%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case {"%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case
{"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, {"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=String method: unexpected EOF)"},
{"%s", PanicS{3}, "%!s(PANIC=3)"}, {"%s", PanicS{3}, "%!s(PANIC=String method: 3)"},
// GoString // GoString
{"%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case {"%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case
{"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"}, {"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=GoString method: unexpected EOF)"},
{"%#v", PanicGo{3}, "%!v(PANIC=3)"}, {"%#v", PanicGo{3}, "%!v(PANIC=GoString method: 3)"},
// Issue 18282. catchPanic should not clear fmtFlags permanently. // Issue 18282. catchPanic should not clear fmtFlags permanently.
{"%#v", []interface{}{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=3), %!v(PANIC=3)}"}, {"%#v", []interface{}{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=GoString method: 3), %!v(PANIC=GoString method: 3)}"},
// Format // Format
{"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
{"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=Format method: unexpected EOF)"},
{"%s", PanicF{3}, "%!s(PANIC=3)"}, {"%s", PanicF{3}, "%!s(PANIC=Format method: 3)"},
} }
func TestPanics(t *testing.T) { func TestPanics(t *testing.T) {
......
...@@ -538,7 +538,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune) { ...@@ -538,7 +538,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune) {
} }
} }
func (p *pp) catchPanic(arg interface{}, verb rune) { func (p *pp) catchPanic(arg interface{}, verb rune, method string) {
if err := recover(); err != nil { if err := recover(); err != nil {
// If it's a nil pointer, just say "<nil>". The likeliest causes are a // If it's a nil pointer, just say "<nil>". The likeliest causes are a
// Stringer that fails to guard against nil or a nil pointer for a // Stringer that fails to guard against nil or a nil pointer for a
...@@ -561,6 +561,8 @@ func (p *pp) catchPanic(arg interface{}, verb rune) { ...@@ -561,6 +561,8 @@ func (p *pp) catchPanic(arg interface{}, verb rune) {
p.buf.WriteString(percentBangString) p.buf.WriteString(percentBangString)
p.buf.WriteRune(verb) p.buf.WriteRune(verb)
p.buf.WriteString(panicString) p.buf.WriteString(panicString)
p.buf.WriteString(method)
p.buf.WriteString(" method: ")
p.panicking = true p.panicking = true
p.printArg(err, 'v') p.printArg(err, 'v')
p.panicking = false p.panicking = false
...@@ -577,7 +579,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) { ...@@ -577,7 +579,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) {
// Is it a Formatter? // Is it a Formatter?
if formatter, ok := p.arg.(Formatter); ok { if formatter, ok := p.arg.(Formatter); ok {
handled = true handled = true
defer p.catchPanic(p.arg, verb) defer p.catchPanic(p.arg, verb, "Format")
formatter.Format(p, verb) formatter.Format(p, verb)
return return
} }
...@@ -586,7 +588,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) { ...@@ -586,7 +588,7 @@ func (p *pp) handleMethods(verb rune) (handled bool) {
if p.fmt.sharpV { if p.fmt.sharpV {
if stringer, ok := p.arg.(GoStringer); ok { if stringer, ok := p.arg.(GoStringer); ok {
handled = true handled = true
defer p.catchPanic(p.arg, verb) defer p.catchPanic(p.arg, verb, "GoString")
// Print the result of GoString unadorned. // Print the result of GoString unadorned.
p.fmt.fmtS(stringer.GoString()) p.fmt.fmtS(stringer.GoString())
return return
...@@ -604,13 +606,13 @@ func (p *pp) handleMethods(verb rune) (handled bool) { ...@@ -604,13 +606,13 @@ func (p *pp) handleMethods(verb rune) (handled bool) {
switch v := p.arg.(type) { switch v := p.arg.(type) {
case error: case error:
handled = true handled = true
defer p.catchPanic(p.arg, verb) defer p.catchPanic(p.arg, verb, "Error")
p.fmtString(v.Error(), verb) p.fmtString(v.Error(), verb)
return return
case Stringer: case Stringer:
handled = true handled = true
defer p.catchPanic(p.arg, verb) defer p.catchPanic(p.arg, verb, "String")
p.fmtString(v.String(), verb) p.fmtString(v.String(), verb)
return return
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment