fatih / errwrap Goto Github PK
View Code? Open in Web Editor NEWGo tool to wrap and fix errors with the new %w verb directive
Home Page: https://arslan.io
License: Other
Go tool to wrap and fix errors with the new %w verb directive
Home Page: https://arslan.io
License: Other
Hello!
go-errorlint is more popular linter, because it's a part of golangci-lint.
And it has functionality to detect %w
:
https://github.com/polyfloyd/go-errorlint#fmterrorf-wrapping-verb
:(
Is there an intentional limit on the number of fixes to apply in a single invocation? I noticed that if I use errwrap to attempt to migrate a legacy project to using 1.13 style error wrapping, it takes a few invocations to make it fix everything:
% errwrap -fix .
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:86:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:89:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:92:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:95:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:98:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:101:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:126:10: call could wrap the error with error-wrapping directive %w
% errwrap -fix .
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:98:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:95:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:101:10: call could wrap the error with error-wrapping directive %w
/Users/example/.local/src/github.ibm.com/org/repo/pkg/action/metrics/screenshot.go:126:10: call could wrap the error with error-wrapping directive %w
% errwrap -fix .
%
The current latest release still has the old broken x/tools. Can you cut a new tag so install@latest will have the bugfixes?
$ go install github.com/fatih/errwrap@latest
$ errwrap --fix ./e2e/...
errwrap: internal error: package "strings" without types was imported from "<snip>"
$ go install github.com/fatih/errwrap@d3e5aba47356be0b258b309dbe2c30b7c195521a
$ errwrap --fix ./e2e/...
<snip>:24:15: call could wrap the error with error-wrapping directive %w
...
I am new to workflows but I think it might be nice to enable it for PRs, too?
Or is it supposed to run on forks? If so, it's a bit inconvenient to see if PRs follow the expected standards.
if err := os.Rename(sourceFilename, destinationFilename); err != nil { - err = fmt.Errorf("Could not move file: %v to %v: %v", - sourceFilename, destinationFilename, err) + err = fmt.Errorf("Could not move file: %v to %v: %w", + sourceFilename, destinationFilename, err) log.Add("err", err)
$ head -1 go.mod module github.com/tmm1/myproj $ errwrap ./... errwrap: ./... matched no packages
IMHO this great tool will reach a far wider audience if it is made part of https://github.com/golangci/golangci-lint
Hi @fatih,
Thank you for providing this linter. It has already helped catch several cases where I did not use the %w
error-wrapping directive in my projects.
It did however flag one case that may be a false-positive.
I have a project that is still using Go 1.19 and the linter identifies what it believes to be a missing use of %w
, but I already have one such usage in place. I understand that this syntax would be valid in Go 1.20, but since the project README indicates that the linter supports Go 1.16 and newer I'm reporting this as a potential problem.
Short version (before following linter advice):
annotatedErrors := make([]error, 0, len(errs))
// ...
annotatedErrors = append(annotatedErrors, fmt.Errorf(
"%w: %v; %s",
err,
errRuntimeTimeoutReached,
runtimeTimeoutReachedAdvice,
))
Linter output:
$ errwrap main.go
main.go:41:48: call could wrap the error with error-wrapping directive %w
Code after following linter advice:
// main.go
package main
import (
"context"
"errors"
"fmt"
)
// errRuntimeTimeoutReached indicates that plugin runtime exceeded specified
// timeout value.
var errRuntimeTimeoutReached = errors.New("plugin runtime exceeded specified timeout value")
// runtimeTimeoutReachedAdvice offers advice to the sysadmin for routine
// occurrence.
const runtimeTimeoutReachedAdvice string = "consider increasing value if this is routinely encountered"
func annotateError(errs ...error) []error {
isNilErrCollection := func(collection []error) bool {
if len(collection) != 0 {
for _, err := range errs {
if err != nil {
return false
}
}
}
return true
}
switch {
// Process errors as long as the collection is not empty or not composed
// entirely of nil values.
case !isNilErrCollection(errs):
annotatedErrors := make([]error, 0, len(errs))
for _, err := range errs {
if err != nil {
switch {
case errors.Is(err, context.DeadlineExceeded):
annotatedErrors = append(annotatedErrors, fmt.Errorf(
"%w: %w; %s",
err,
errRuntimeTimeoutReached,
runtimeTimeoutReachedAdvice,
))
default:
// Record error unmodified if additional decoration isn't defined
// for the error type.
annotatedErrors = append(annotatedErrors, err)
}
}
}
return annotatedErrors
// No errors were provided for evaluation.
default:
return nil
}
}
func main() {
sampleErr := fmt.Errorf(
"my sample error: %w",
context.DeadlineExceeded,
)
errCollection := annotateError(sampleErr)
fmt.Println(errCollection)
}
// main_test.go
package main
import (
"context"
"fmt"
"testing"
)
func TestAnnotateError(t *testing.T) {
sampleErr := fmt.Errorf(
"my sample error: %w",
context.DeadlineExceeded,
)
errCollection := annotateError(sampleErr)
t.Log(errCollection)
}
If I follow the linter's advice, this is what I get when running the code:
$ go run main.go
[my sample error: context deadline exceeded: %!w(*errors.errorString=&{plugin runtime exceeded specified timeout value}); consider increasing value if this is routinely encountered]
$ go test ./...
# errwrap-false-positive
.\main.go:41:48: fmt.Errorf call has more than one error-wrapping directive %w
FAIL errwrap-false-positive [build failed]
FAIL
$ go version -m $(which errwrap.exe)
C:/Users/atc0005/go/bin/errwrap.exe: go1.19.7
path github.com/fatih/errwrap
mod github.com/fatih/errwrap v1.5.0 h1:/z6jzrekbYYeJukzq9h3nY+SHREDevEB0vJYC4kE9D0=
dep golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
dep golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
dep golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
build -compiler=gc
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=amd64
build GOOS=windows
build GOAMD64=v1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.