Update errorlint to HEAD (#1933)

This commit is contained in:
Ludovic Fernandez 2021-05-01 18:41:26 +02:00 committed by GitHub
parent 34ffdc243f
commit a7865d2430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 153 additions and 86 deletions

View File

@ -118,8 +118,12 @@ linters-settings:
exclude: /path/to/file.txt
errorlint:
# Report non-wrapping error creation using fmt.Errorf
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
errorf: true
# Check for plain type assertions and type switches
asserts: true
# Check for plain error comparisons
comparison: true
exhaustive:
# check switch statements in generated files also

2
go.mod
View File

@ -57,7 +57,7 @@ require (
github.com/nishanths/exhaustive v0.1.0
github.com/nishanths/predeclared v0.2.1
github.com/pkg/errors v0.9.1
github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f
github.com/polyfloyd/go-errorlint v0.0.0-20210418123303-74da32850375
github.com/ryancurrah/gomodguard v1.2.0
github.com/ryanrolds/sqlclosecheck v0.3.0
github.com/sanposhiho/wastedassign v0.2.0

4
go.sum generated
View File

@ -495,8 +495,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4=
github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
github.com/polyfloyd/go-errorlint v0.0.0-20210418123303-74da32850375 h1:uuOfAQo7em74dKh41UzjlQ6dXmE9wYxjvUcfg2EHTDw=
github.com/polyfloyd/go-errorlint v0.0.0-20210418123303-74da32850375/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=

View File

@ -62,7 +62,9 @@ var defaultLintersSettings = LintersSettings{
ExtraRules: false,
},
ErrorLint: ErrorLintSettings{
Errorf: true,
Errorf: true,
Asserts: true,
Comparison: true,
},
Ifshort: IfshortSettings{
MaxDeclLines: 1,
@ -165,7 +167,9 @@ type ErrcheckSettings struct {
}
type ErrorLintSettings struct {
Errorf bool `mapstructure:"errorf"`
Errorf bool `mapstructure:"errorf"`
Asserts bool `mapstructure:"asserts"`
Comparison bool `mapstructure:"comparison"`
}
type ExhaustiveSettings struct {

View File

@ -10,17 +10,21 @@ import (
func NewErrorLint(cfg *config.ErrorLintSettings) *goanalysis.Linter {
a := errorlint.NewAnalyzer()
cfgMap := map[string]map[string]interface{}{}
if cfg != nil {
cfgMap[a.Name] = map[string]interface{}{
"errorf": cfg.Errorf,
"errorf": cfg.Errorf,
"asserts": cfg.Asserts,
"comparison": cfg.Comparison,
}
}
return goanalysis.NewLinter(
"errorlint",
"go-errorlint is a source code linter for Go software "+
"that can be used to find code that will cause problems "+
"with the error wrapping scheme introduced in Go 1.13.",
a.Name,
"errorlint is a linter for that can be used to find code "+
"that will cause problems with the error wrapping scheme introduced in Go 1.13.",
[]*analysis.Analyzer{a},
cfgMap,
).WithLoadMode(goanalysis.LoadModeTypesInfo)

View File

@ -0,0 +1,5 @@
linters-settings:
errorlint:
errorf: false
asserts: true
comparison: false

View File

@ -0,0 +1,5 @@
linters-settings:
errorlint:
errorf: false
asserts: false
comparison: true

View File

@ -0,0 +1,5 @@
linters-settings:
errorlint:
errorf: true
asserts: false
comparison: false

View File

@ -3,88 +3,29 @@ package testdata
import (
"errors"
"fmt"
"log"
)
var errFoo = errors.New("foo")
var errLintFoo = errors.New("foo")
func doThing() error {
return errFoo
type errLintBar struct{}
func (*errLintBar) Error() string {
return "bar"
}
func compare() {
err := doThing()
if errors.Is(err, errFoo) {
log.Println("ErrFoo")
func errorLintAll() {
err := func() error { return nil }()
if err == errLintFoo { // ERROR "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
if err == nil {
log.Println("nil")
}
if err != nil {
log.Println("nil")
}
if nil == err {
log.Println("nil")
}
if nil != err {
log.Println("nil")
}
if err == errFoo { // ERROR "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errFoo")
}
if err != errFoo { // ERROR "comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("not errFoo")
}
if errFoo == err { // ERROR "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errFoo")
}
if errFoo != err { // ERROR "comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("not errFoo")
}
switch err { // ERROR "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors"
case errFoo:
log.Println("errFoo")
}
switch doThing() { // ERROR "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors"
case errFoo:
log.Println("errFoo")
}
}
type myError struct{}
err = errors.New("oops")
fmt.Errorf("error: %v", err) // ERROR "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"
func (*myError) Error() string {
return "foo"
}
func doAnotherThing() error {
return &myError{}
}
func typeCheck() {
err := doAnotherThing()
var me *myError
if errors.As(err, &me) {
log.Println("myError")
}
_, ok := err.(*myError) // ERROR "type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors"
if ok {
log.Println("myError")
}
switch err.(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError")
}
switch doAnotherThing().(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError")
}
switch t := err.(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError", t)
}
switch t := doAnotherThing().(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError", t)
case *errLintBar:
log.Println("errLintBar")
}
}

46
test/testdata/errorlint_asserts.go vendored Normal file
View File

@ -0,0 +1,46 @@
//args: -Eerrorlint
//config_path: testdata/configs/errorlint_asserts.yml
package testdata
import (
"errors"
"log"
)
type myError struct{}
func (*myError) Error() string {
return "foo"
}
func errorLintDoAnotherThing() error {
return &myError{}
}
func errorLintAsserts() {
err := errorLintDoAnotherThing()
var me *myError
if errors.As(err, &me) {
log.Println("myError")
}
_, ok := err.(*myError) // ERROR "type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors"
if ok {
log.Println("myError")
}
switch err.(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError")
}
switch errorLintDoAnotherThing().(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError")
}
switch t := err.(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError", t)
}
switch t := errorLintDoAnotherThing().(type) { // ERROR "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors"
case *myError:
log.Println("myError", t)
}
}

53
test/testdata/errorlint_comparison.go vendored Normal file
View File

@ -0,0 +1,53 @@
//args: -Eerrorlint
//config_path: testdata/configs/errorlint_comparison.yml
package testdata
import (
"errors"
"log"
)
var errCompare = errors.New("foo")
func errorLintDoThing() error {
return errCompare
}
func errorLintComparison() {
err := errorLintDoThing()
if errors.Is(err, errCompare) {
log.Println("errCompare")
}
if err == nil {
log.Println("nil")
}
if err != nil {
log.Println("nil")
}
if nil == err {
log.Println("nil")
}
if nil != err {
log.Println("nil")
}
if err == errCompare { // ERROR "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
if err != errCompare { // ERROR "comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("not errCompare")
}
if errCompare == err { // ERROR "comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("errCompare")
}
if errCompare != err { // ERROR "comparing with != will fail on wrapped errors. Use errors.Is to check for a specific error"
log.Println("not errCompare")
}
switch err { // ERROR "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors"
case errCompare:
log.Println("errCompare")
}
switch errorLintDoThing() { // ERROR "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors"
case errCompare:
log.Println("errCompare")
}
}

View File

@ -1,5 +1,5 @@
//args: -Eerrorlint
//config: linters-settings.errorlint.errorf=true
//config_path: testdata/configs/errorlint_errorf.yml
package testdata
import (
@ -13,7 +13,7 @@ func (customError) Error() string {
return "oops"
}
func wraps() {
func errorLintErrorf() {
err := errors.New("oops")
fmt.Errorf("error: %w", err)
fmt.Errorf("error: %v", err) // ERROR "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"