Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

log/slog: LogValuer implementation panics on nil value #70069

Closed
denpeshkov opened this issue Oct 27, 2024 · 5 comments
Closed

log/slog: LogValuer implementation panics on nil value #70069

denpeshkov opened this issue Oct 27, 2024 · 5 comments

Comments

@denpeshkov
Copy link

Go version

go1.23 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/denpeshkov/Library/Caches/go-build'
GOENV='/Users/denpeshkov/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/denpeshkov/go/pkg/mod'
GONOPROXY='gitlab.wildberries.ru/sender'
GONOSUMDB='gitlab.wildberries.ru/sender'
GOOS='darwin'
GOPATH='/Users/denpeshkov/go'
GOPRIVATE='gitlab.wildberries.ru/sender'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.23.2/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.23.2/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.2'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/denpeshkov/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/denpeshkov/src/gitlab.wildberries.ru/sender/sender-template/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/xx/y0wxwyw553j3s155ywc95mqw0000gn/T/go-build141366395=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Go Playground link

What did you see happen?

2009/11/10 23:00:00 INFO Message text foo="LogValue panicked\ncalled from runtime.panicwrap (/usr/local/go-faketime/src/runtime/error.go:355)\ncalled from main.(*foo).LogValue (:1)\ncalled from log/slog.Value.Resolve (/usr/local/go-faketime/src/log/slog/value.go:512)\ncalled from log/slog.(*handleState).appendAttr (/usr/local/go-faketime/src/log/slog/handler.go:468)\ncalled from log/slog.(*handleState).appendNonBuiltIns.func1 (/usr/local/go-faketime/src/log/slog/handler.go:342)\n(rest of stack elided)\n"

What did you expect to see?

2009/11/10 23:00:00 INFO Message text foo=

@seankhliao
Copy link
Member

this looks working as intended for slog, the issue is in your code

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2024
@denpeshkov
Copy link
Author

denpeshkov commented Oct 27, 2024

Thanks for your reply! Just to confirm, do I need to handle nil values explicitly even if the method receiver is defined on a value rather than a pointer?

Even without accessing struct fields, I'm encountering a panic: https://go.dev/play/p/vott61McxDf?v=gotip

@seankhliao
Copy link
Member

given a pointer, Go needs to dereference it to pass to the method. That's where your nil pointer dereference is coming from. It also panics if you call f.LogValue() directly, without slog.

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@denpeshkov
Copy link
Author

I was just thinking it would be helpful if this behaved similarly to fmt.Stringer when handling nil values. It explicitly handles nil in panic:

// If it's a nil pointer, output "<nil>". This approach could handle cases 
// where a Stringer might not check for nil or where a nil pointer is used 
// with a value receiver. In both scenarios, "<nil>" seems like a reasonable default.
if v := reflect.ValueOf(arg); v.Kind() == reflect.Pointer && v.IsNil() {
    p.buf.writeString(nilAngleString)
    return
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants