Skip to content
This repository was archived by the owner on May 9, 2021. It is now read-only.

Commit c72d1a5

Browse files
leonelquinterosandybons
authored andcommitted
lint: avoid false positives with custom errors-package
When using `errors.New(fmt.Sprintf(...))`, lint will alert that you should use `fmt.Errorf(...)`. Before this patch, this alert was also displayed when using a custom errors-package. There are valid use cases to use `errors.New(fmt.Sprintf(...))` in a custom errors-package context. This patch avoids the "false positive" alert when a custom errors-package is imported in the current file. Fixes #350 Change-Id: I7cc82a3435b184f8b4cad0752a75d44f33536dce GitHub-Last-Rev: ad257d2 GitHub-Pull-Request: #360 Reviewed-on: https://go-review.googlesource.com/96091 Reviewed-by: Andrew Bonventre <andybons@golang.org>
1 parent fb4f8c1 commit c72d1a5

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lint.go

+18
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"unicode"
2424
"unicode/utf8"
2525

26+
"golang.org/x/tools/go/ast/astutil"
2627
"golang.org/x/tools/go/gcexportdata"
2728
)
2829

@@ -1126,6 +1127,9 @@ func (f *file) lintErrorf() {
11261127
if !isErrorsNew && !isTestingError {
11271128
return true
11281129
}
1130+
if !f.imports("errors") {
1131+
return true
1132+
}
11291133
arg := ce.Args[0]
11301134
ce, ok = arg.(*ast.CallExpr)
11311135
if !ok || !isPkgDot(ce.Fun, "fmt", "Sprintf") {
@@ -1694,6 +1698,20 @@ func (f *file) srcLineWithMatch(node ast.Node, pattern string) (m []string) {
16941698
return rx.FindStringSubmatch(line)
16951699
}
16961700

1701+
// imports returns true if the current file imports the specified package path.
1702+
func (f *file) imports(importPath string) bool {
1703+
all := astutil.Imports(f.fset, f.f)
1704+
for _, p := range all {
1705+
for _, i := range p {
1706+
uq, err := strconv.Unquote(i.Path.Value)
1707+
if err == nil && importPath == uq {
1708+
return true
1709+
}
1710+
}
1711+
}
1712+
return false
1713+
}
1714+
16971715
// srcLine returns the complete line at p, including the terminating newline.
16981716
func srcLine(src []byte, p token.Position) string {
16991717
// Run to end of line in both directions if not at line start/end.

testdata/errorf-custom.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Test for allowed errors.New(fmt.Sprintf()) when a custom errors package is imported.
2+
3+
// Package foo ...
4+
package foo
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/pkg/errors"
10+
)
11+
12+
func f(x int) error {
13+
if x > 10 {
14+
return errors.New(fmt.Sprintf("something %d", x)) // OK
15+
}
16+
if x > 5 {
17+
return errors.New(g("blah")) // OK
18+
}
19+
if x > 4 {
20+
return errors.New("something else") // OK
21+
}
22+
return nil
23+
}
24+
25+
func g(s string) string { return "prefix: " + s }

0 commit comments

Comments
 (0)