Code Monkey home page Code Monkey logo

go-err113's Introduction

err113 GoDoc Build Status Coverage Status

Table of Contents

Golang linter to check the errors handling expressions

Details

Starting from Go 1.13 the standard error type behaviour was changed: one error could be derived from another with fmt.Errorf() method using %w format specifier.

So the errors hierarchy could be built for flexible and responsible errors processing.

And to make this possible at least two simple rules should be followed:

  1. error values should not be compared directly but with errors.Is() method.

  2. error should not be created dynamically from scratch but by the wrapping the static (package-level) error.

This linter is checking the code for these 2 rules compliance.

Reports

So, err113 reports every == and != comparison for exact error type variables except comparison to nil and io.EOF.

Also, any call of errors.New() and fmt.Errorf() methods are reported except the calls used to initialise package-level variables and the fmt.Errorf() calls wrapping the other errors.

Note: non-standard packages, like github.com/pkg/errors are ignored completely.

Install

go get -u github.com/Djarvur/go-err113/cmd/err113

Usage

Defined by singlechecker package.

err113: checks the error handling rules according to the Go 1.13 new error type

Usage: err113 [-flag] [package]


Flags:
  -V	print version and exit
  -all
    	no effect (deprecated)
  -c int
    	display offending line with this many lines of context (default -1)
  -cpuprofile string
    	write CPU profile to this file
  -debug string
    	debug flags, any subset of "fpstv"
  -fix
    	apply all suggested fixes
  -flags
    	print analyzer flags in JSON
  -json
    	emit JSON output
  -memprofile string
    	write memory profile to this file
  -source
    	no effect (deprecated)
  -tags string
    	no effect (deprecated)
  -trace string
    	write trace log to this file
  -v	no effect (deprecated)

Thanks

To Iskander (Alex) Sharipov for the really useful advices.

To Jack Whelpton for the bugfix provided.

go-err113's People

Contributors

onokonem avatar sayboras avatar takady avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

go-err113's Issues

Strictness with parametrized errors

Often, errors require parameters, e.g.:

return nil, fmt.Errorf("unknown storage provider '%s'", providerName)

These aren't errors that need a statically/globally defined type, nor is there an error available which we can wrap. Both errors.New and fmt.Errorf report errors with err113, but there isn't a clear way to resolve them. Should the error be reported, if we're not passing an error typed parameter for %w?

Handling panic errors

How to make panic errors wrapped static

if rec := recover(); rec != nil {
	trace := debug.Stack()

	err = fmt.Errorf("PANIC [%v] TRACE[%s]", rec, string(trace))
}

linter error

err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"PANIC [%v] TRACE[%s]\", rec, string(trace))"

Non-standard errors package not being ignored

The documentation explicitly states:

Note: non-standard packages, like github.com/pkg/errors are ignored complitely.

However, if I write the following code:

package main

import (
	"fmt"

	"github.com/pkg/errors"
)

func main() {
	err := errors.New("option failed")
	fmt.Println(err)
}

and execute err113 ., I see:

C:\Projects\localhost\tst\main.go:10:9: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"option failed\")"

Issue with -fix flag

While running go-err113 with -fix flag, I got weird replacement, some can be listed as below:

err == http.ErrServerClosed -> errors.Is(err, &{http ErrServerClosed})
ctx.Err() == context.DeadlineExceeded -> errors.Is(&{%!s(*ast.SelectorExpr=&{0xc005394f00 0xc005394f20}) %!s(token.Pos=67939731) [] %!s(token.Pos=0) %!s(token.Pos=67939732)}, &{context DeadlineExceeded})

More proofs please

Hello!

Go 1.13 provides a mechanism for wrapping through %w, but this does not mean that now you can refuse libraries like https://github.com/pkg/errors, which provides a more convenient api for working with errors.

Also this absolutely does not mean that you should use errors.Is() everywhere instead of == (adding yourself an overhead for recursion). It all depends on the context of the program.

Is there anywhere documented evidence that this is how errors should be handled?

Nowtime it looks like a very crude idea for linter.

Comparison with go-errorlint (https://github.com/polyfloyd/go-errorlint)

Hello!

At the moment, in golangci-lint, we have two linters that perform the same functionality.

Your linter appeared later, but it seems to have more options.

I would suggest:

  1. Implement errors.As (#14)
  2. Make exceptions / flags for dynamic errors (#10)
  3. As a request from me: to require the creation of an error through the error.New if there are no formatting arguments:
var MyError  = fmt.Errorf("some error")
  1. Support type switches.

And then that go-errorlint can be asked to archive :)

What do you think? If you do not mind the points above, I can try to find the time and help you implement them.

Question about errors that are just a string

Greetings and thanks for the linter.

The linter doesn't seem to like the following code:

func testingSubroutine(i1 int, i2 int) error {
    if i1 != i2 {
        return errors.New("i1 and i2 are not equal!")
    }

    return nil
}

It gives the error:

err113: do not define dynamic errors, use wrapped static errors instead

However, this seems nonsensical, because there is nothing to wrap. I'm just creating a brand new error. Is this a bug in the linter or am I misunderstanding the error message?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.