-
Notifications
You must be signed in to change notification settings - Fork 20.2k
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
all: fix warning flagging the use of DeepEqual on error #23624
Conversation
core/genesis.go
Outdated
func (e *GenesisMismatchError) Is(target error) bool { | ||
gme, ok := target.(*GenesisMismatchError) | ||
if !ok { | ||
return false | ||
} | ||
return bytes.Equal(e.Stored[:], gme.Stored[:]) && | ||
bytes.Equal(e.New[:], gme.New[:]) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this whole thing needed? I'm thinking we can replace it with
var ErrGenesisMismatch = errors.New("genesis mismatch")
And in the places where we now instantiate it, we simply do
return fmt.Errorf("%w: database has %x, new %x", ErrGenesisMismatch, have, new)
And then we can just do the generic errors.Is
for it, instead of implementing custom Is
support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reasons explained previously, this method is not useful for any production use of the error.
params/config.go
Outdated
func (err *ConfigCompatError) Is(target error) bool { | ||
cce, ok := target.(*ConfigCompatError) | ||
if !ok { | ||
return false | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here -- can we just simplify it?
BTW, I think this PR is a bit weird. Using reflect.DeepEqual for errors is totally fine in tests, there is no downside to it. I think it complains about this because using DeepEqual for errors is discouraged in non-test code. This is because DeepEqual cannot find the error if it is wrapped in another one, but errors.Is can. We need to think twice about the semantics of errors.Is here. The way it's implemented now, the error will only match if all fields are exactly the same. For example, in order to get a match with errors.Is is not meant for this kind of check, it is intended for matching against certain known constant errors such as os.ErrExist. For ConfigCompatError, it is more appropriate to use errors.As and then check the fields yourself:
I'd argue that, since you will always need to deal with values of concrete type ConfigCompatError in order to use it properly, reflect.DeepEqual is appropriate for this type, and errors.Is cannot help. |
I tend to think along @holiman 's suggestion: use the |
What I meant is: errors.Is works best if you are looking for an error that is constant, like in For ConfigCompatError specifically, it is not possible to use errors.Is in the place where we look for it, which is here. But we could use errors.As there, it would work. Also, it is not a good idea to replace this particular error with a constant + use of %w because ConfigCompatError also contains the block number where the mismatch is. |
Most changes you made are fine. The change for ConfigCompatError needs to be reverted because errors.Is cannot be used with this error. I think we can live with one instance of reflect.DeepEqual in unit tests for this. For GenesisMismatchError, we could technically use %w like Martin said. I personally think it is not worth the effort, and keeping existing API stable is preferred over changing it to satisfy the lint tool. |
d99e6ba
to
ca03e14
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* core: fix warning flagging the use of DeepEqual on error * apply the same change everywhere possible * revert change that was committed by mistake * fix build error * Update config.go * revert changes to ConfigCompatError * review feedback Co-authored-by: Felix Lange <[email protected]>
* core: fix warning flagging the use of DeepEqual on error * apply the same change everywhere possible * revert change that was committed by mistake * fix build error * Update config.go * revert changes to ConfigCompatError * review feedback Co-authored-by: Felix Lange <[email protected]>
* core: fix warning flagging the use of DeepEqual on error * apply the same change everywhere possible * revert change that was committed by mistake * fix build error * Update config.go * revert changes to ConfigCompatError * review feedback Co-authored-by: Felix Lange <[email protected]>
gopls
returns a warning thatreflect.DeepEqual
should not be used onerror
. This PR replaces it with a call toerrors.Is
introduced in Go 1.13.Not all tests are replaced, only those for which
Is(error)
can be implemented. For example, some errors in thenet
package don't implement it.