> 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.

Reply via email to