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

error-compare: detect contains of err.Error() #47

Open
Limero opened this issue Jan 5, 2024 · 4 comments
Open

error-compare: detect contains of err.Error() #47

Limero opened this issue Jan 5, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@Limero
Copy link

Limero commented Jan 5, 2024

Running testifylint on a large codebase at work I noticed that people sometimes use Contains to check error messages, something that testifylint currently doesn't detect

Expected results:

assert.Contains(t, err.Error(), "error")
     require.Contains(t, err.Error(), "error")
     s.Contains(err.Error(), "error")

✅   assert.ErrorContains(t, err, "error")
     require.ErrorContains(t, err, "error")
     s.ErrorContains(err, "error")
@Antonboom
Copy link
Owner

Hi!

Thank you for feedback.
Related to https://github.com/Antonboom/testifylint/blob/master/CONTRIBUTING.md#error-compare

@Antonboom Antonboom added the enhancement New feature or request label Jan 9, 2024
@nickajacks1
Copy link

I see that assert.ErrorContains(t, err, "not found") is discouraged in favor of ErrorIs. I agree with that guidance when it's an option, but sometimes errors are unexported, meaning you have no choice but to use ErrorContains. I understand that checking the error string is a bit fragile, but what alternatives would you suggest? Perhaps simply assert.Error?

Some justification I can think of for using assert.Error alone and ignoring the content of the error is that if your actual code can't check the type of error that is returned, that means that the content of the error doesn't affect the control flow, and thus the unit tests shouldn't need to be coupled to the human-readable error messages.

@ccoVeille
Copy link
Contributor

For records, I started working on the implementation of this feature request.

https://github.com/Antonboom/testifylint/blob/master/CONTRIBUTING.md#error-compare

Stay tuned, and ping me if you see no progress in the next month.

@ccoVeille
Copy link
Contributor

I agree with @Limero @nickajacks1 there is a need for a checker that will look for detecting this.

assert.Contains(t, err.Error(), "error") require.Contains(t, err.Error(), "error") s.Contains(err.Error(), "error")

This should be a checker activated by default.

As @Antonboom said, there is a need for a checker these by .ErrorContains(t, err, ErrSentinel)

But these are two separate needs. While the first one is legitimate and should be activated by default. The second one is more opinionated and could lead to problems.

We have to consider ErrorContains could be used for wrapped error to check one word is present in the error message

Let's consider a code returning that

fmt.Errorf("error %w - code %s, ErrSentinel, "foo")

I would use

assert.ErrorIs(t, err, ErrSentinel)

but then I would use

assert.ErrorContains(t, err, "foo")

These use cases are legitimate.

But I agree we should also prevent the following pattern and suggest to use Error.Is

assert.Contains(t, err.Error(), ErrSentinel.Error())

This is pattern was sometimes used before testify.Error.Is and even errors.Is existed in standard lib.

@Antonboom Antonboom changed the title feature: Detect Contains err.Error() error-compare: Detect Contains err.Error() Jun 5, 2024
@Antonboom Antonboom changed the title error-compare: Detect Contains err.Error() error-compare: detect Contains err.Error() Jun 5, 2024
@Antonboom Antonboom changed the title error-compare: detect Contains err.Error() error-compare: detect contains of err.Error() Jun 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants