mirror of
https://github.com/mgechev/revive.git
synced 2025-02-01 13:07:44 +02:00
Merge 'ads-lost-err'
Conflicts: config.go
This commit is contained in:
commit
8ffd0e86d3
@ -53,6 +53,7 @@ var allRules = append([]lint.Rule{
|
|||||||
&rule.ModifiesParamRule{},
|
&rule.ModifiesParamRule{},
|
||||||
&rule.DeepExitRule{},
|
&rule.DeepExitRule{},
|
||||||
&rule.ADSPrintRule{},
|
&rule.ADSPrintRule{},
|
||||||
|
&rule.ADSLostErrRule{},
|
||||||
}, defaultRules...)
|
}, defaultRules...)
|
||||||
|
|
||||||
var allFormatters = []lint.Formatter{
|
var allFormatters = []lint.Formatter{
|
||||||
|
9
fixtures/ads-lost-err.go
Normal file
9
fixtures/ads-lost-err.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func foo(a, b, c, d int) {
|
||||||
|
errors.New("aaa")
|
||||||
|
errors.New(errors.InternalError, errors.MessageOption("nice error message "+err.Error())) // MATCH /original error is lost, consider using errors.NewFromError/
|
||||||
|
errors.MessageOption("nice error message " + err.Error())
|
||||||
|
}
|
95
rule/ads-lost-err.go
Normal file
95
rule/ads-lost-err.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package rule
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/ast"
|
||||||
|
|
||||||
|
"github.com/mgechev/revive/lint"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ADSLostErrRule lints program exit at functions other than main or init.
|
||||||
|
type ADSLostErrRule struct{}
|
||||||
|
|
||||||
|
// Apply applies the rule to given file.
|
||||||
|
func (r *ADSLostErrRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||||
|
var failures []lint.Failure
|
||||||
|
onFailure := func(failure lint.Failure) {
|
||||||
|
failures = append(failures, failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := lintLostErr{onFailure, "errors", "New"}
|
||||||
|
ast.Walk(w, file.AST)
|
||||||
|
return failures
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the rule name.
|
||||||
|
func (r *ADSLostErrRule) Name() string {
|
||||||
|
return "ads-lost-err"
|
||||||
|
}
|
||||||
|
|
||||||
|
type lintLostErr struct {
|
||||||
|
onFailure func(lint.Failure)
|
||||||
|
targetPkg string
|
||||||
|
targetFunc string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w lintLostErr) Visit(node ast.Node) ast.Visitor {
|
||||||
|
ce, ok := node.(*ast.CallExpr)
|
||||||
|
if !ok {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg, fn := getPkgFunc(ce)
|
||||||
|
|
||||||
|
if pkg == w.targetPkg && fn == w.targetFunc {
|
||||||
|
if pkg == "errors" && fn == "New" {
|
||||||
|
w.targetFunc = "MessageOption"
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
s := searchErr{&w, ce}
|
||||||
|
for _, exp := range ce.Args {
|
||||||
|
ast.Walk(s, exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.targetFunc = "New"
|
||||||
|
}
|
||||||
|
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
type searchErr struct {
|
||||||
|
w *lintLostErr
|
||||||
|
fc *ast.CallExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s searchErr) Visit(node ast.Node) ast.Visitor {
|
||||||
|
|
||||||
|
id, ok := node.(*ast.Ident)
|
||||||
|
if !ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if id.Name == "err" {
|
||||||
|
s.w.onFailure(lint.Failure{
|
||||||
|
Confidence: 0.8,
|
||||||
|
Node: s.fc,
|
||||||
|
Category: "bad practice",
|
||||||
|
Failure: "original error is lost, consider using errors.NewFromError",
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPkgFunc(ce *ast.CallExpr) (string, string) {
|
||||||
|
fc, ok := ce.Fun.(*ast.SelectorExpr)
|
||||||
|
if !ok {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
id, ok := fc.X.(*ast.Ident)
|
||||||
|
if !ok {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return id.Name, fc.Sel.Name
|
||||||
|
}
|
11
test/ads-lost-err_test.go
Normal file
11
test/ads-lost-err_test.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mgechev/revive/rule"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestADSLostErr(t *testing.T) {
|
||||||
|
testRule(t, "ads-lost-err", &rule.ADSLostErrRule{})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user