Hacker News new | past | comments | ask | show | jobs | submit login

The one that got me was the implicit wrapping of structs into interface types. As an example, the below code segfaults with `fatal error: panic while printing panic value: type runtime.errorString`:

    package main
    
    type SomeError struct {
        SomeMessage   string
    }
    
    func (se *SomeError) Error() string {
        return se.SomeMessage
    }
    
    func doSomethingSomeWay() *SomeError {
        return nil
    }
    
    func DoSomething() error {
        return doSomethingSomeWay()
    }
    
    func main() {
        err := DoSomething()
        if err != nil {
            panic(err)
        }
    }



      func doSomethingSomeWay() *SomeError {
Yeah, you'd never return a concrete error like this -- clear red flag in any code review.

For precisely the reason you're demonstrating here! (Among several others.)


100% agree.

But do we have linting tools that raise this as an issue?


"Linting" this isn't really possible, because it's really beyond what a linter can handle. It would take a full static analysis job to determine that there's a problem, because there isn't any individual line of code that's wrong.

In this code, the error lies in the combination of all three of:

1. doSomethingSomeWay unconditionally returns a nil pointer.

2. That nil pointer claims to implement the error interface, but it is lying. If you actually call error on it, it will panic no matter what. But since the nil is not removable (no non-nil pointer types) this sometimes happens in real code, even though in this case it's obviously a faked up problem.

3. The main function packs the *SomeError into an error, then calls the method on it that will crash.

As this code. I would call it wrong if it had the type signature "func () error"; then it is definitively the part of the code that is lying and packing a value into an interface that does not implement that interface. But the example as written doesn't quite have any one line or function that a linter, generally simpler than static analysis, can pick up on.

(You may be surprised that I don't simply blame the code in main. I can explain why: https://www.jerf.org/iri/post/2957/ and a followup https://jerf.org/iri/post/2023/value_validity/ . It's actually an entry point into a very important thing for high-level programmers to understand, even well beyond Go.)


As jerf says, not really easily, no. But code review is a perfectly reasonable mechanism for catching this kind of thing.


I can't answer that, but the poster mentions it segfaults so it's identified that way for sure.


nil interfaces are not equal to nil values in Golang. Interfaces are fat pointers with a type and value pair and if the type is populated then the pointer as a whole will not compare to the `nil` value as it requires both elements to be nil. Frankly, I think this was a design mistake.


Yes, this has to do with interface values and how interfaces are implemented in Go. It's a bit weird.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: