> Am 19.08.2025 um 00:22 schrieb Kevin Chowski <ke...@chowski.com>: > > Regarding the "var _ error" bit - why not just look at the Error method to > see whether it is on a T or a *T? I haven't done a survey about it or > anything, but if I need to know whether to pass a T or a *T I often check > that type's methods.
Unfortunately looking at receiver types does not work, lots of errors have a value receiver but are meant as pointer values. The linter is meant to work with existing codebases without API changes, improving the status quo. Adding a “var _ error” is basically free and no API change. > On Friday, August 15, 2025 at 5:10:42 AM UTC-6 Oliver Eikemeier wrote: >> Static Analysis for Go Error Type Consistency: errortype Linter >> >> I've been investigating a class of subtle bugs in Go error handling related >> to pointer vs. value semantics with errors.As, and developed a static >> analysis tool to detect these issues. I'm seeking feedback from the >> community on both the approach and the tool's effectiveness. >> >> Problem Statement >> >> Consider this code attempting to handle AES key size errors: >> >> key := []byte("My kung fu is better than yours") >> _, err := aes.NewCipher(key) >> >> var kse *aes.KeySizeError >> if errors.As(err, &kse) { >> fmt.Printf("AES keys must be 16, 24 or 32 bytes long, got %d >> bytes.\n", kse) >> } else if err != nil { >> fmt.Println(err) >> } >> The bug: aes.NewCipher returns aes.KeySizeError as a value, but the code >> checks for a pointer to *aes.KeySizeError. This type mismatch causes >> errors.As to fail silently, with no compile-time detection. >> >> Analysis and Solution Approach >> >> The core issue is that Go's error interface allows both pointer and value >> types to implement error, but the dynamic type matching in errors.As >> requires exact type correspondence. This creates opportunities for silent >> failures when the expected and actual types don't align. >> >> I propose a two-part mitigation strategy: >> >> 1. Compile-time Intent Declaration >> >> Explicit compile-time assertions to document intended usage patterns: >> >> // MyValueError is intended to be used as a value >> var _ error = MyValueError{} >> >> // MyPointerError is intended to be used as a pointer >> var _ error = (*MyPointerError)(nil) >> 2. Static Analysis Tool >> >> I've developed errortype, a static analyzer that detects inconsistencies >> between intended error type usage and actual usage patterns. The tool >> analyzes: >> >> Function return value types >> Type assertions and type switches >> errors.As target parameters >> Method receiver consistency patterns >> Example diagnostic output: >> >> main.go:14:20: Target for value error "crypto/aes.KeySizeError" is a >> pointer-to-pointer, use a pointer to a value instead: "var kse >> aes.KeySizeError; ... errors.As(err, &kse)". (et:err) >> Request for Feedback >> >> I'm particularly interested in feedback on a few points: >> >> Prevalence: Have you encountered this pointer/value ambiguity with error >> types? How common do you think this class of bug is in practice? >> Solution Approach: What are your thoughts on using var _ error = ... >> assertions to declare an error type's intended usage? Is this a practical >> convention to adopt? >> Tooling: The detection heuristics are based on these assertions and usage >> pattern analysis. I would be grateful for any real-world testing on your >> codebases to validate their effectiveness and performance. >> The tool is currently CLI-only while I refine the detection logic based on >> real-world usage patterns. Integration is planned in a later phase. >> >> References >> >> Detailed analysis: https://blog.fillmore-labs.com/posts/errors-1/ >> Tool repository: https://github.com/fillmore-labs/errortype >> Playground example: https://go.dev/play/p/m4SEPqkZ2Zu >> I welcome any insights, particularly from those who have encountered similar >> issues or have thoughts on static analysis approaches for Go error handling >> patterns. >> >> Best regards, Oliver >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/B5042084-6E73-4651-AB06-39169795FFA0%40fillmore-labs.com.