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

feat: add errchkjson linter #2349

Closed
wants to merge 7 commits into from
Closed

Conversation

breml
Copy link
Member

@breml breml commented Nov 6, 2021

Add errchkjson.

This linter checks the types, that are passed to json encoding function (e.g. json.Marshal) and has two main functions:

  1. Reports types, that are not supported for json encoding (e.g. complex128, func or chan).
  2. Reports when the error returned from the json encoding function can be ignored, because there is no way for json.Marshal to have an error.

For more details, see the README.md.

(This linter has been laying around on my harddisk for 2 years, after the successful inclusion of bidichk in golangci-lint (#2330) I felt motivated to polish this one and propose it for inclusion as well.)

@breml breml requested a review from ldez November 6, 2021 11:19
test/testdata/errchkjson.go Outdated Show resolved Hide resolved
test/testdata/errchkjson_omit_safe.go Outdated Show resolved Hide resolved
test/testdata/errchkjson_omit_safe.go Outdated Show resolved Hide resolved
pkg/golinters/errchkjson.go Outdated Show resolved Hide resolved
@ldez ldez added the linter: new Support new linter label Nov 6, 2021
test/testdata/errchkjson.go Outdated Show resolved Hide resolved
test/testdata/errchkjson.go Outdated Show resolved Hide resolved
test/testdata/errchkjson.go Outdated Show resolved Hide resolved
test/testdata/errchkjson.go Outdated Show resolved Hide resolved
test/testdata/errchkjson.go Outdated Show resolved Hide resolved
test/testdata/errchkjson_omit_safe.go Outdated Show resolved Hide resolved
test/testdata/errchkjson_omit_safe.go Outdated Show resolved Hide resolved
test/testdata/errchkjson_omit_safe.go Outdated Show resolved Hide resolved
test/testdata/errchkjson_omit_safe.go Outdated Show resolved Hide resolved
@breml
Copy link
Member Author

breml commented Nov 6, 2021

@ldez Thanks for finding all the typos. I will rebase all the changes as soon as I am back at my keyboard.

@breml breml force-pushed the add-errchkjson branch 2 times, most recently from 4c161ac to 8dc2b87 Compare November 7, 2021 20:40
@breml
Copy link
Member Author

breml commented Nov 7, 2021

@ldez rebased all the typo changes and updated to errchkjson v0.1.1, which adds a check for structs without any exported fields (as requested on reddit)

@breml
Copy link
Member Author

breml commented Nov 7, 2021

@ldez What do you think about this comment on reddit?

Interesting, but the basic errcheck linter would probably conflict with the decisions of this one, no?. It gets mad whenever there is a possible error value that you don't check, even if it's "unreachable".

My tests suggest, that there is no problem, if the err is omitted with _. But there might be a problem, if the the error is omitted entirely, for example with:

enc := json.NewEncoder(os.Stdout)
enc.Encode(xyz) // error is omitted

Is there a way to throw away a report from an other linter (in this case errcheck), because errchkjson is more specific?

@ldez
Copy link
Member

ldez commented Nov 7, 2021

updated to errchkjson v0.1.1, which adds a check for structs without any exported fields (as requested on reddit)

This check is already done by another linter: https://staticcheck.io/docs/checks/#SA9005

@ldez
Copy link
Member

ldez commented Nov 7, 2021

Is there a way to throw away a report from an other linter (in this case errcheck), because errchkjson is more specific?

A linter cannot interact with another linter.

@ldez
Copy link
Member

ldez commented Nov 7, 2021

IMO, for the golangci-lint context, your linter must not handle the error and let the other linters, that are specific to this, handle the error.

breml added a commit to breml/errchkjson that referenced this pull request Nov 8, 2021
This flag is needed to disable this check in order to prevent
duplicate check results with staticcheck in golangci-lint.

See:
* golangci/golangci-lint#2349 (comment)
* https://staticcheck.io/docs/checks/#SA9005
@breml
Copy link
Member Author

breml commented Nov 8, 2021

IMO, for the golangci-lint context, your linter must not handle the error and let the other linters, that are specific to this, handle the error.

I do not agree with this, because errcheck is generic in the sense that it reports every occasion, where an arbitrary function returns an error and this error is omitted. errchkjson is more specific in the sense, that it is limited to the json encoding functions but in contrast to errcheck it does understand the different cases, when the json encoding functions in fact may return an error and in which cases it is safe to ignore the error.

Therefore I tried to find a way, how these two linters can co-exist and both perform their job to the best extend possible. The latest commit is the current solution I found so far.

breml and others added 7 commits November 8, 2021 23:53
if errchkjson is enabled and omit-safe is not activated.

In this case, the check for the errors in errchkjson
is superior to the "generic" check in errcheck.
Therefore we instruct errcheck to ignore these
cases and let errchkjson handle them.
Update pkg/golinters/errchkjson.go
Update test/testdata/errchkjson.go
Update test/testdata/errchkjson_omit_safe.go

Co-authored-by: Ludovic Fernandez <ldez@users.noreply.github.com>
@breml
Copy link
Member Author

breml commented Nov 12, 2021

Is there anything missing on this PR? What is the best way to move forward with this?

@breml breml requested a review from ldez November 12, 2021 15:54
Comment on lines +25 to +36
// Modify errcheck config if this linter is enabled and OmitSafe is false
if isEnabled(linters, a.Name) && !omitSafe {
if errcheckCfg == nil {
errcheckCfg = &config.ErrcheckSettings{}
}
errcheckCfg.ExcludeFunctions = append(errcheckCfg.ExcludeFunctions,
"encoding/json.Marshal",
"encoding/json.MarshalIndent",
"(*encoding/json.Encoder).Encode",
)
}

Copy link
Member

Choose a reason for hiding this comment

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

As I already said, a linter cannot interact with another linter.

The fact to create links between 2 linters means that 1 linter can be a part of the other linter.

Copy link
Member Author

Choose a reason for hiding this comment

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

@ldez Thanks for having a look at my PR again, I really appreciate it.

As I already said, a linter cannot interact with another linter.

I do not exactly understand what you mean by "cannot". My understanding of "cannot" is, that it is technically not possible. But I don't think this is true, because the implementation of the PR does work as intended.
Or do you mean "cannot" in the sense of "MUST NOT" (or "SHALL NOT") as defined in https://datatracker.ietf.org/doc/html/rfc2119? That is: it is prohibited by guideline (even though, it could technically be possible).
If it is the later, I would like to know, if this guideline is written down somewhere and I would like to better understand the reasoning behind it. I understand, that in some cases the exclude patterns have been used to handle exactly such situations, e.g. for duplicates between gosec and errcheck (see EXC0008).

The fact to create links between 2 linters means that 1 linter can be a part of the other linter.
So what is your recommendation? I can see the following options (in no particular order):

  1. Add the functionality of errchkjson to errcheck. I do not know, if this special handling is in the scope of errcheck, because it defines its scope pretty general with "... checking for unchecked errors ..." and as far as I can tell, there is currently no special handling based on the input arguments in errcheck. Additionally, errchkjson also performs checks on the input types for the json encoding functions (can a type be encoded) and this is cleary out of scope for errcheck and would have to stay in this linter.
  2. Extend errchkjson to also include everything that is done by errcheck so the user is free to choose one linter or the other depending of the fact, if he wants to have the special handling of the json encoding functions. In my opinion, this does not make any sense.
  3. We add the necessary exceptions to the ExcludePatterns in pkg/config/issues.go, but I am not sure how exactly this would work given the fact, that the exclude pattern should only be added under special circumstances (both linters enabled and omitSafe not true).
  4. Add the errchkjson linter (without adding config settings to errcheck) and mention in the documentation / .golangci-lint.yaml, how the user can add the necessary excludes. This would work, but it is not really user friendly.
  5. Keep the current implementation.

@ldez ldez added the feedback required Requires additional feedback label Nov 13, 2021
@breml breml removed the feedback required Requires additional feedback label Nov 13, 2021
@breml breml mentioned this pull request Nov 16, 2021
@ldez ldez closed this in #2362 Nov 26, 2021
@breml breml deleted the add-errchkjson branch November 27, 2021 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linter: new Support new linter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants