What does HackerNews think of errcheck?

errcheck checks that you checked errors.

Language: Go

#1 in Go
https://github.com/kisielk/errcheck

Every Go project I've worked on has used this linter. I think it should be builtin, but it's very easy to incorporate.

https://github.com/kisielk/errcheck, which is in most of the combined linter packages by default.

We'll agree to disagree about unused imports; imports have can side-effects.

> Go compiler raise an error if a variable (error) goes unused

It doesn't though. It's not a warning or error to not use the return value of a function that only returns an error, for instance (https://go.dev/play/p/se6-zHHVezH).

There are static error checking tools you can use like https://github.com/kisielk/errcheck to work around this, but most people don't use them.

I've run into a lack of Go error checking many times. Many times it's just the trivial case, where the compiler doesn't warn about not checking the result of an error-returning function.

But often it'll be subtler, and the result of Go's API design. One example is its file writing API, which requires you to close the file and check its error to be correct. Many times people will just `defer file.Close()`, but that isn't good enough - you're ignoring the error there.

Worse still is e.g: writing to a file through a bufio.Writer. To be correct, you need to remember to flush the writer, check that error, then close the file and check that error. There's no type-level support to make sure you do that.

I'd be really happy with that! Building the functionality of errcheck[1] and ineffassign[2] into the compiler — or at the very least, into govet — would go a long way to allay my worries with Go.

I think the reason they don't do this is that it's a slight (albeit a very tiny one) against Go's philosophy of errors being values, just like any other. While the `error` type is standard and used throughout Go source code, it still just has a simple three-line definition[3] and is not treated as a special case anywhere else; there is nothing stopping you from returning your own error type if you wish. A third-party linter could simply check for the `error` type specifically, but the first-party tools should not, and there's nothing like Rust's `#[must_use]` attribute that could be used instead. I respect Go's philosophy, but I feel like pragmatism must win in this case.

[1]: https://github.com/kisielk/errcheck [2]: https://github.com/gordonklaus/ineffassign [3]: https://pkg.go.dev/builtin#error

My bad, I was thinking of errcheck, which is more thorough and integrated into most Go linting tools like Go CI linter.

https://github.com/kisielk/errcheck

In any case, it’s trivial to detect via static analysis.

> Go does absolutely nothing to ensure you handle the error.

Go has many community linters available, https://github.com/kisielk/errcheck is popular for checking unhandled errors.

If you'd like a combo-pack, check out https://github.com/golangci/golangci-lint which includes all of the popular linters in a configurable way.

The errcheck linter is very popular for checking that you looked at every error return: https://github.com/kisielk/errcheck

I use it in most of my open source projects.

Staticcheck is inavluable, and I support it with words, actions, and money. Here are some additional tools that you might want to have in your module's tools.go:

* github.com/kisielk/errcheck[1]: Find cases where you (accidentally?) ignore errors.

* github.com/gordonklaus/ineffassign[2]: Find ineffectial assignments; sounds simple, almost unneeded, but in my practice it's actually one of the most effective analyses to find actual bugs.

* mvdan.cc/unparam[3]: Find functions that always consume or return one value; great for refactorings.

[1] https://github.com/kisielk/errcheck

[2] https://github.com/gordonklaus/ineffassign

[3] https://github.com/mvdan/unparam

> I found it too easy to accidentally forget to check an error

Use https://github.com/kisielk/errcheck for that.

Or prefer https://staticcheck.io/ for a larger set of checks.

for examples like this it is much better to explicit ignore error:

_ = index.Index(identifier, your_data)

it will also pass https://github.com/kisielk/errcheck check

eventually we can just panic error

if err := index.Index(identifier, your_data); err != nil { panic(err) }

There is a useful linter named `errcheck` for Go which looks for swallowed or shadowed errors [1]. It's included in `gometalinter` [2] (which is worth running as part of the CI checks on any Go codebase).

[1] https://github.com/kisielk/errcheck [2] https://github.com/alecthomas/gometalinter

Another clear lang vs tool split present in Go is related to returning the error type. The language could enforce that return values of type error must always be assigned (and used). But it doesn't, and now there's the errcheck tool.

https://github.com/kisielk/errcheck

I agree that having things like errcheck and go-sumtype all wired up using gometalinter is pretty novel and only partially gross.

> There are no guide rails telling you that you forgot to check an error result. This is a runtime thing you need to discover. Is this actually simpler?

This may be considered cheating since it isn't baked into the language but there are tools to do this at build time, here's one: https://github.com/kisielk/errcheck

Go makes it really easy to linters (lexer and parser in standard library, simple AST, etc.), so there is a robust linger for that: https://github.com/kisielk/errcheck
It is very easy to produce linters for Go to find things like unchecked errors, for example https://github.com/kisielk/errcheck
> here we have something that's much simpler, yet super repetitive and should be easy to catch on compile time.

It is easy to catch on compile time. https://github.com/kisielk/errcheck

> I really prefer the Java "force you to catch exception" model much more to this.

https://github.com/kisielk/errcheck/ will tell you if you silently discard the `err` value (though you can still explicitly assign it to _ to ignore). Seems worth using for a lot of projects.

Which you can catch with a linter like https://github.com/kisielk/errcheck. Errors in Go are just values. There's nothing "more wrong" about ignoring a return value that is an error or one that is file handle, for example. And in cases where a function returns an error and a value (where the error generally indicates the validity of the value), you'll get a compile error if you don't check the error. That's pretty good for basically zero overhead.
You can always call a function and not assign the return calls to anything.

If you have

func foo() (string, error)

You can still call it thusly:

foo()

However there are tools to check for unchecked errors like this one: https://github.com/kisielk/errcheck

> think most of this could be solved easily by either a compiler option or golint rule

You mean like errcheck? https://github.com/kisielk/errcheck

I'm not sure if it can find spots where people intentionally throw away an error like in

    val, _ := foo()
Usually people are more concerned with places where people accidentally fail to realize there's an error returned at all, like this:

    func foo() error { ... }

    foo() // errcheck finds this
However, it should be possible to find errors assigned to underscores, and thus detect that case.
In practice this is not a problem that is encountered pretty much ever. If you are afraid of it, run errcheck[1] on your code, and it'll tell you if you've missed anything.

[1] https://github.com/kisielk/errcheck

This is true, you can drop all return values. However, a lot of functions return a value and an error. If you want to access the value, you need to assign the error to something too. And if you don't then use that error, the compiler will complain about it.

For simply dropping all return values on the ground, there are linters that will complain for you: https://github.com/kisielk/errcheck

Yeah... so far my Go stuff has had exceptional reliability, I verified I handled all error known conditions with errcheck (https://github.com/kisielk/errcheck) and just generally took the slow and plodding approach of handling everything explicitly. My app handles hundreds of thousands of concurrent connections, each one often using and/or spawning 4 or more goroutines.
Below, mseepgood pointed out https://github.com/kisielk/errcheck exists--looks excellent.

(Still would be cool if the Gophers put something like it in the std distro.)

You can't stop people from being lazy. Look at all the Java and Python code that forcefully ignores exceptions.

It is something that can be caught with static analysis, however. Someone recently put together an appropriate tool[1] for Go, in fact. It seems to work very well.

[1]https://github.com/kisielk/errcheck