Comments (11)
My opinion is that this is a bug in the implementation of the String method on the value. The String method should return a valid string for a nil pointer. Calling a method on a nil pointer is perfectly acceptable in Go. A contrived example:
http://play.golang.org/p/hQS__z15cT
package main
import "fmt"
func main() {
m1 := new(mutable)
*m1 = 0
for i := 0; i < 5; i++ {
m1.add(2)
fmt.Println(m1)
}
var m2 *mutable
fmt.Println(m2)
}
type mutable int
func (m *mutable) add(v int) {
if m != nil {
*m += mutable(v)
}
}
func (m *mutable) String() string {
if m == nil {
return "<nil>"
}
return fmt.Sprint(*m)
}
So I think the real question is: Should log15 take steps to not trigger these types of bugs in client code? I am not ready to answer that question yet.
from log15.
So for my String(), I've typically been using a value based receiver, primarily because all the snippets I've seen does this. So when I receive the panic, my String would be something like:
func (m mutable) String() string {
return fmt.Sprint(m)
}
I did find that if I used a pointer based receiver AND I handled the nil case, it would work. I'm more than happy to switch over to do that. As a matter of curiosity, when it comes to String, is it better to do pointer v. value? Minus the reason of size. In the end it probably is better I use pointer based, since some of the structs are a little large.
from log15.
There is not one right answer for when to use a pointer or value based receiver. This question comes up often and the answer depends on the specifics of your code. Typically String() string
should not be modifying the value, and typically the cost of formatting the data into a string will significantly outweigh the cost of copying the value. So in general I would favor a value receiver for String() string
methods unless I had hard evidence that a pointer receiver was required.
from log15.
Getting back to your original problem. Having re-read your initial post more carefully I did not fully understand the issue. I see now that you have a type with a value based String() string
method, but you are passing a nil
pointer to such a value in the context.
I was curious what the fmt
package does in this case: http://play.golang.org/p/SINT-YfkrK. It prints <nil>
. But I have reproduced your report that log15 panics. I think we should do better than that and we should fix this in log15.
from log15.
I did a some research into how the fmt
package handles this situation and prints <nil>
. It recover()
s the panic and only then uses the reflect
package to check if the value is a nil pointer.
See https://github.com/golang/go/blob/go1.4.1/src/fmt/print.go#L704 and https://github.com/golang/go/blob/go1.4.1/src/fmt/print.go#L624 for the code.
from log15.
Good find Chris. It seems to me that if fmt.Printf supports that, we should support it as well.
from log15.
Cool, thanks for the info. Before I had submitted the issue I had found:
http://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go
And here is a thread with more on interfaces with nil value but type.
from log15.
@mobileben Thanks for the links, both are helpful.
from log15.
I've just pushed a fix for this issue.
@mobileben & @inconshreveable please review.
from log15.
LGTM
from log15.
Yep, looks good. I'll also undo my work around change in the code I found this issue with and confirm it there.
from log15.
Related Issues (20)
- Add Illumos support HOT 1
- support log rotate HOT 3
- Expose the runtime.Callers skip HOT 1
- tag a new release HOT 1
- v2.12 Build Issues HOT 3
- Support for a kv-generating interface on log arguments
- Normal log15.Root() not colorized on Cygwin
- logfmt/json keys for msg/lvl/t are hard-coded HOT 3
- Allow logging in UTC HOT 2
- Use Semantic Version Tags compatible with the new Go modules HOT 1
- Please add a go.mod file HOT 1
- make NetHandler able to log to an URL?
- No way to close files opened when a new FileHandler is created.
- Default Lvl is LvlCrit HOT 1
- proposal: add Fatal() HOT 1
- Test failure while building v2.15
- Use semantic versioning to satisfy `go mod`
- Is this library maintained? HOT 3
- CallerFileHandler should include package name
- Different outputs for different functions
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from log15.