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

solver: use errors.Is when checking context.Cause() #4587

Merged
merged 1 commit into from
Jan 25, 2024

Conversation

jedevc
Copy link
Member

@jedevc jedevc commented Jan 25, 2024

Since the change to replace uses of context.WithCancel with WithCancelCause in #4457, we've also begun wrapping all cancellations using errors.WithStack. This means that these would not directly match context.Canceled, so we need to make sure to use errors.Is.

I spotted this while reading over #4457 in more detail again, I wonder if this is the source of a particular deadlock we're encountering where gRPC streams aren't shutting down (though this may or may not be the actual root cause lol). That said, this code definitely seems wrong.

Ideally, we should have some linter check to prevent comparing errors like this at all - direct comparisons on errors should be the exception rather than the rule. cc @crazy-max do you know if this exists?

Since the change to replace uses of context.WithCancel with
WithCancelCause, we've also begun wrapping all cancellations using
errors.WithStack. This means that these would not directly match
context.Canceled, so we need to make sure to use errors.Is.

Signed-off-by: Justin Chadwell <me@jedevc.com>
@jedevc jedevc requested review from tonistiigi and sipsma January 25, 2024 13:04
@crazy-max
Copy link
Member

crazy-max commented Jan 25, 2024

direct comparisons on errors should be the exception rather than the rule

💯

cc @crazy-max do you know if this exists?

I don't think golangci-lint includes a built-in linter specifically for enforcing the use of errors.Is over direct error comparisons. However, we might be able to achieve this with custom linter rules or by using an external linter that can be integrated into golangci-lint. I will take a look. @thaJeztah Maybe you have some input on this?

if err != nil && context.Cause(ctx) == context.Canceled {
if err != nil && errors.Is(context.Cause(ctx), context.Canceled) {
Copy link
Member

Choose a reason for hiding this comment

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

We're only interested in cancelled contexts, here, correct? (as they commonly go hand-in-hand with DeadlineExceeded); e.g. moby/moby#46444

@thaJeztah
Copy link
Member

It wouldn't surprise me if revive has checks for this somewhere in its options (it has a lot of additional checks that are disabled by default).

@thaJeztah
Copy link
Member

Very orthogonal, but may be of interest here as well; there's some work in progress on moving containerd's errdefs package to a separate module. @dmcgowan is looking if that package can be compatible with BOTH "moby's" errdefs package (which uses interfaces for matching) and containerd's errdefs (which uses types). If that works, we're considering unifying on a single errdefs package, which can ease handling of various error-types that may cross boundaries.

see https://github.com/containerd/errdefs

@jedevc
Copy link
Member Author

jedevc commented Jan 25, 2024

It wouldn't surprise me if revive has checks for this somewhere in its options (it has a lot of additional checks that are disabled by default).

Had a quick check through the options on https://revive.run/docs#available-rules, doesn't appear that there's one that ticks the box for us.

@tonistiigi tonistiigi merged commit c1a9bdb into moby:master Jan 25, 2024
63 checks passed
@jedevc jedevc deleted the use-errors-is branch January 26, 2024 00:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants