diff --git a/wrapcheck/testdata/interface_on_struct/main.go b/wrapcheck/testdata/interface_on_struct/main.go index f845015..c2cf892 100644 --- a/wrapcheck/testdata/interface_on_struct/main.go +++ b/wrapcheck/testdata/interface_on_struct/main.go @@ -1,12 +1,8 @@ package main -import ( - "encoding/json" - "strings" -) - type errorer interface { Decode(v interface{}) error + decode(v interface{}) error } type foo struct { @@ -14,8 +10,8 @@ type foo struct { } func main() { - d := json.NewDecoder(strings.NewReader("hello world")) - do(foo{d}) + do(foo{}) + doInternal(foo{}) } func do(f foo) error { @@ -27,3 +23,13 @@ func do(f foo) error { return nil } + +func doInternal(f foo) error { + var str string + err := f.bar.decode(&str) + if err != nil { + return err // unexported methods are validated at their implementation + } + + return nil +} diff --git a/wrapcheck/wrapcheck.go b/wrapcheck/wrapcheck.go index 79e7bba..2c1b2d2 100644 --- a/wrapcheck/wrapcheck.go +++ b/wrapcheck/wrapcheck.go @@ -283,9 +283,9 @@ func reportUnwrapped( } // Check if the underlying type of the "x" in x.y.z is an interface, as - // errors returned from interface types should be wrapped, unless ignored - // as per `ignoreInterfaceRegexps` - if isInterface(pass, sel) { + // errors returned from exported interface types should be wrapped, unless + // ignored as per `ignoreInterfaceRegexps` + if sel.Sel.IsExported() && isInterface(pass, sel) { pkgPath := pass.TypesInfo.ObjectOf(sel.Sel).Pkg().Path() name := types.TypeString(pass.TypesInfo.TypeOf(sel.X), func(p *types.Package) string { return p.Name() }) if !containsMatch(regexpsInter, name) && !containsMatchGlob(pkgGlobs, pkgPath) {