Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable ErrCheck #5386

Merged
merged 13 commits into from May 14, 2020
Merged

Enable ErrCheck #5386

merged 13 commits into from May 14, 2020

Conversation

ogaca-dd
Copy link
Contributor

@ogaca-dd ogaca-dd commented Apr 22, 2020

What does this PR do?

This PR enables ErrCheck.
errcheck is a program for checking for unchecked errors in go programs.

Additional Notes

As handling errors may lead to behavior changes, I disabled existing warnings with //nolint:errcheck.

New codes should explicitly handle the errors. In the rare cases you want to discard the error use something like _ := MyFunction().

@ogaca-dd ogaca-dd added [deprecated] team/agent-core Deprecated. Use metrics-logs / shared-components labels instead.. changelog/no-changelog labels Apr 22, 2020
@ogaca-dd ogaca-dd requested review from a team as code owners April 22, 2020 15:44
@ogaca-dd ogaca-dd requested review from a team as code owners April 22, 2020 17:13
@ogaca-dd ogaca-dd added this to the 7.20.0 milestone Apr 23, 2020
olivielpeau
olivielpeau previously approved these changes May 7, 2020
Copy link
Member

@olivielpeau olivielpeau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this linter makes sense to me, and the approach of ignoring the existing non-check errors in this initial PR sounds good as well.

How much does this linter add to the linter wall clock time on a dev env ? Does it support linting only a subset of the packages? (wouldn't want to slow down invoke test by too much, especially when invoke test --targets=./pkg/foo is specified for example)

Copy link
Contributor

@prognant prognant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember if we have subsequent action planned to handle all the places requiring the //nolint:errcheck assertion, but I guess we will see later.

.golangci.yml Outdated
linters-settings:
errcheck:
# Disable warnings for `fmt` and `log` packages.
ignore: fmt:.*,github.com/DataDog/datadog-agent/pkg/util/log:.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the huge number of http.ResponseWriter.write(...) requiring the //nolint:errcheck would it be possible to exclude it ? (possible errors seem relatively safe to ignore https://golang.org/pkg/net/http/#pkg-variables but I may be wrong about that)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to ignore http.ResponseWriter.Write a couple of days ago but because of golangci/golangci-lint#656, it seems I can only ignore all the Write methods from http package (and not the specific method http.ResponseWriter.Write).
Upgrading golangci-lint requires extra work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @prognant, I'm not a fan of all the //nolint:errcheck. We might want to ignore all Write() call from the http package at this point.

As a more general review, we ignore so many warning in this PR that I wonder if it's worth it. I feel like it's increasing the code complexity and we're not gaining a lot. Like all call to json or yaml should actually be fixed instead of being ignore. WDYT ?

I'm afraid people are not actually going to check their error but just pollute the code base with //nolint:errcheck. At this point we will fall back to where we are now: relying on review instead of the linter. That's why I didn't enabled it in the first PR for golangci: way to many warning we might not want to fix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my 2 cents:

  • I guess it makes sense for the linter to ignore all Write calls from the http package. Let's add a fixme comment linking to the golanci issue, we might be able to make the ignore rule more specific when we upgrade golangci
  • I prefer explicitly calling out all instances of unhandled errors with //nolint:errcheck than having errors "silently" ignored in the code (by "silent" here, I mean that the calling code doesn't even acknowledge that the call can return an error)
  • merging this with a bunch of //nolint:errcheck is simpler to review and merge, and already provides value for future code we'll add to the codebase. But yes please create tasks in the backlog about cleaning up all these //nolint:errcheck (one card per team owning related packages)

@ogaca-dd
Copy link
Contributor Author

ogaca-dd commented May 7, 2020

@olivielpeau

How much does this linter add to the linter wall clock time on a dev env ?

Measurements based of the median of 3 runs for time invoke test --targets=./pkg/aggregator
before:

real    0m24.182s
user    0m55.739s
sys     0m18.056s

after:

real    0m24.293s
user    0m55.490s
sys     0m18.228s

Does it support linting only a subset of the packages? (wouldn't want to slow down invoke test by too much, especially when invoke test --targets=./pkg/foo is specified for example

I only enabled a new linter and so the behavior is the same as before.

.golangci.yml Show resolved Hide resolved
.golangci.yml Outdated
linters-settings:
errcheck:
# Disable warnings for `fmt` and `log` packages.
ignore: fmt:.*,github.com/DataDog/datadog-agent/pkg/util/log:.*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @prognant, I'm not a fan of all the //nolint:errcheck. We might want to ignore all Write() call from the http package at this point.

As a more general review, we ignore so many warning in this PR that I wonder if it's worth it. I feel like it's increasing the code complexity and we're not gaining a lot. Like all call to json or yaml should actually be fixed instead of being ignore. WDYT ?

I'm afraid people are not actually going to check their error but just pollute the code base with //nolint:errcheck. At this point we will fall back to where we are now: relying on review instead of the linter. That's why I didn't enabled it in the first PR for golangci: way to many warning we might not want to fix.

@ogaca-dd
Copy link
Contributor Author

@hush-hush :

I agree with @prognant, I'm not a fan of all the //nolint:errcheck. We might want to ignore all Write() call from the http package at this point.

Write methods in net/http are now ignored by ErrCheck.

As a more general review, we ignore so many warning in this PR that I wonder if it's worth it. I feel like it's increasing the code complexity and we're not gaining a lot. Like all call to json or yaml should actually be fixed instead of being ignore. WDYT ?

At first, I wanted to fix everything but I realized that I do not well enough the impacted code to do the changes.

I'm afraid people are not actually going to check their error but just pollute the code base with //nolint:errcheck. At this point we will fall back to where we are now: relying on review instead of the linter. That's why I didn't enabled it in the first PR for golangci: way to many warning we might not want to fix.

I think ErrCheck linter is one the most useful linters of golangci-lint as not checking an error can lead to a bug.

At this point we will fall back to where we are now: relying on review instead of the linter.
Without Errcheck it is very hard during a review to catch error not checked so I think it will make a big difference compared to the current situation.

I'm afraid people are not actually going to check their error but just pollute the code base with //nolint:errcheck

There are some rare cases where ignoring error is the right thing. _ can be used and is shorter and easier to remember than //nolint:errcheck.
Indeed, new //nolint:errcheck might be added. If we really want to avoid it, we can add a check that count the number of //nolint:errcheck. What do you think?

…rg/errcheck

# Conflicts:
#	cmd/cluster-agent/app/app.go
#	pkg/clusteragent/clusterchecks/dispatcher_main.go
#	pkg/clusteragent/clusterchecks/handler.go
#	pkg/forwarder/forwarder_health.go
#	pkg/jmxfetch/jmxfetch.go
@ogaca-dd ogaca-dd merged commit af24c65 into master May 14, 2020
@hush-hush hush-hush deleted the olivierg/errcheck branch May 14, 2020 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog/no-changelog [deprecated] team/agent-core Deprecated. Use metrics-logs / shared-components labels instead..
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants