Skip to content

Commit

Permalink
Update errorlint to HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Apr 30, 2021
1 parent 12ed5fa commit 006afb9
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 86 deletions.
6 changes: 5 additions & 1 deletion .golangci.example.yml
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions pkg/config/linters_settings.go
Expand Up @@ -62,7 +62,9 @@ var defaultLintersSettings = LintersSettings{
ExtraRules: false,
},
ErrorLint: ErrorLintSettings{
Errorf: true,
Errorf: true,
Asserts: true,
Comparison: true,
},
Ifshort: IfshortSettings{
MaxDeclLines: 1,
Expand Down Expand Up @@ -164,7 +166,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 {
Expand Down
14 changes: 9 additions & 5 deletions pkg/golinters/errorlint.go
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions test/testdata/configs/errorlint_asserts.yml
@@ -0,0 +1,5 @@
linters-settings:
errorlint:
errorf: false
asserts: true
comparison: false
5 changes: 5 additions & 0 deletions test/testdata/configs/errorlint_comparison.yml
@@ -0,0 +1,5 @@
linters-settings:
errorlint:
errorf: false
asserts: false
comparison: true
5 changes: 5 additions & 0 deletions test/testdata/configs/errorlint_errorf.yml
@@ -0,0 +1,5 @@
linters-settings:
errorlint:
errorf: true
asserts: false
comparison: false
87 changes: 14 additions & 73 deletions test/testdata/errorlint.go
Expand Up @@ -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 compare() {
err := doThing()
if errors.Is(err, errFoo) {
log.Println("ErrFoo")
}
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")
}
func (*errLintBar) Error() string {
return "bar"
}

type myError struct{}

func (*myError) Error() string {
return "foo"
}
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")
}

func doAnotherThing() error {
return &myError{}
}
err = errors.New("oops")
fmt.Errorf("error: %v", err) // ERROR "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors"

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 changes: 46 additions & 0 deletions test/testdata/errorlint_asserts.go
@@ -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 changes: 53 additions & 0 deletions test/testdata/errorlint_comparison.go
@@ -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")
}
}
4 changes: 2 additions & 2 deletions test/testdata/errorlint_errorf.go
@@ -1,5 +1,5 @@
//args: -Eerrorlint
//config: linters-settings.errorlint.errorf=true
//config_path: testdata/configs/errorlint_errorf.yml
package testdata

import (
Expand All @@ -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"
Expand Down

0 comments on commit 006afb9

Please sign in to comment.