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

[WIP] New rule use-errors-new (propose replacing fmt.Errorf by errors.New when possible) #1136

Closed
wants to merge 9 commits into from

Conversation

chavacava
Copy link
Collaborator

WIP PR implementing a new rule use-errors-new that proposes replacing fmt.Errorf by errors.New when possible.

As indicated in this issue, beyond style considerations, errors.News is ~4x faster that fmt.Errorf

I've tested the rule against public code bases like terraform and gitea and it finds hundreds of "failures" (with no false positives, the rule is very simple)

I'm not so happy with the rule name, if you have something better... I take.
I'll complete the PR (tests+doc) in the next days, meanwhile comments are welcome.

cc: @ccoVeille @alexandear

@chavacava chavacava added the rule proposal Issue proposing a new rule label Nov 18, 2024
@chavacava chavacava self-assigned this Nov 18, 2024
@alexandear
Copy link
Contributor

I'm not so happy with the rule name, if you have something better... I take.

The rule name use-errors-new is good, in my opinion.

PR implementing a new rule use-errors-new that proposes replacing fmt.Errorf by errors.New when possible.

There is a linter called perfsprint with a check named errorf that suggests the same. It can be configured and used through golangci-lint via the perfsprint.errorf configuration.

I have done the replacements to errors.New with the help of perfsprint in these PRs:

@ccoVeille
Copy link
Contributor

I was about say there might be another linter that may have the rule.

But I'm fine with having it supported in revive, as it's a specific tool.

But then later, golangci-lint team might report it as a duplicate, maybe they will simply disable it by default.

BTW, do you plan to enable it my default? Or at least to add it to the recommended rules list?

"github.com/mgechev/revive/lint"
)

// UseErrorsNewRule lints given else constructs.
Copy link
Contributor

@ccoVeille ccoVeille Nov 18, 2024

Choose a reason for hiding this comment

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

I don't get this sentence, maybe you could rephrase

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

Choose a reason for hiding this comment

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

No test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As I've said in the PR description, it is work in progress, I'll complete the PR (tests+doc) in the next days.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

tests and doc added

@ccoVeille
Copy link
Contributor

I checked go vet, go critic, errorlint, gosimple. It's not supported

For me, this rule should be a staticcheck one, but each repository deserves a linter maybe. The main issues with different tools, is the fact you are never sure something will get merged by a maintainer.

Here we are in revive, you decide.

But once in golangci-lint, someone may raise a flag. What do you think @ldez?

@ldez
Copy link
Contributor

ldez commented Nov 18, 2024

It already exists inside golangci-lint: perfsprint.

main.go:6:9: fmt.Errorf can be replaced with errors.New (perfsprint)
        return fmt.Errorf("foo")
               ^

#1136 (comment)

@ldez
Copy link
Contributor

ldez commented Nov 18, 2024

To be clear, I have no problem with duplicate rules between golangci-lint and revive.

The 2 projects are independent, so it's expected to have duplicates especially with "metalinters".

Same thing with golangci-lint and staticcheck, or staticcheck and revive, or gocritic and revive, etc.

I try to limit them because it's confusing for users to have 2 elements for the same rule/check but it should not be used as a limitation for other tools.

But I have a problem when someone uses a PR open on Golangci-lint, and so the work of someone else, to create a rule inside another tool.
golangci/golangci-lint#5087

@ccoVeille
Copy link
Contributor

It already exists inside golangci-lint: perfsprint.

Yes, it does. @alexandear already spotted it, and I was looking at other linters (even the experimental ones in gocritic, go vet and gosimple) if it was already available.

And yes, apparently, perfsprint is currently the only one to report it.

To be clear, I have no problem with duplicate rules between golangci-lint and revive.

The 2 projects are independent, so it's expected to have duplicates especially with "metalinters".

Same thing with golangci-lint and staticcheck, or staticcheck and revive, or gocritic and revive, etc.

I try to limit them because it's confusing for users to have 2 elements for the same rule/check but it should not be used as a limitation for other tools.

Thanks for your feedback @ldez

perfsprint detects way more things than what this rule would do, so I would say it's OK, anyway. It's not as if perfsprint was detecting only what is added in this PR. And then, it could become a deprecation logic at some point.
But I'm going too far 😄 as it's not the case.

So now, if someone want to have revive use-errors-new and perfsprint it can still disable use-errors-new or perfsprint.errorf`

It might become a problem only if use-errors-new is added at some point to the revive default linter.
But here again, I'm anticipating too much

Thanks again Ludovic.

But I have a problem when someone uses a PR open on Golangci-lint, and so the work of someone else, to create a rule inside another tool. golangci/golangci-lint#5087

Yes, this one was pretty crazy

@chavacava
Copy link
Collaborator Author

Thank you all for the feedback.

I didn't know about perfsprint. Anyway the fact that there is already a linter that does similar analysis than a rule was never a criterion to decide adding or not the rule to revive.

BTW, do you plan to enable it by default?

I'm not planning to enable it by default.

It might become a problem only if use-errors-new is added at some point to the revive default linter.

Users with enableAllRules = true in the conf will have use-errors-new by default

The rule name use-errors-new is good, in my opinion.

OK, I'll stick to it if I don't find something better.

Category: "errors",
Node: n,
Confidence: 1,
Failure: "replace fmt.Errorf by errors.New ",
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit:

Suggested change
Failure: "replace fmt.Errorf by errors.New ",
Failure: "replace fmt.Errorf by errors.New",

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed

@chavacava chavacava closed this Nov 20, 2024
@chavacava chavacava deleted the feature/use-errors-new branch November 20, 2024 20:27
config/config.go Outdated
Comment on lines 101 to 103
&rule.UseErrorsNewRule{},
&rule.RedundantBuildTagRule{},
&rule.UseErrorsNewRule{},
Copy link
Contributor

Choose a reason for hiding this comment

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

Twice?

Copy link
Contributor

Choose a reason for hiding this comment

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

Likely to be with conflicts, this might explain why #1142 was opened

}

if len(funcCall.Args) > 1 {
return w // the use of fmt.Errorf is legit
Copy link
Contributor

@ccoVeille ccoVeille Nov 20, 2024

Choose a reason for hiding this comment

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

Well, not exactly

We have crazy people out there

fmt.Errorf("%s, "whatever")
https://github.com/search?q=language%3Ago++%22fmt.Errorf%28%5C%22%25s%5C%22%2C+%5C%22%22&type=code

fmt.Errorf("%w", err)
https://github.com/search?q=language%3Ago++%22fmt.Errorf%28%5C%22%25w%5C%22%2C+%22&type=code

I created an issue on perfprint linter, as it's in their scope

I think you can merge like this, with current code.

My point can be addressed later

Copy link
Contributor

Choose a reason for hiding this comment

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

Discussion moved on the PR

#1142 (comment)

@ccoVeille
Copy link
Contributor

ccoVeille commented Nov 20, 2024

Moved to #1142

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rule proposal Issue proposing a new rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants