-
Notifications
You must be signed in to change notification settings - Fork 62
✨ Use error type rather than strings #878
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
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #878 +/- ##
==========================================
+ Coverage 76.21% 77.93% +1.72%
==========================================
Files 17 17
Lines 1177 1142 -35
==========================================
- Hits 897 890 -7
+ Misses 202 175 -27
+ Partials 78 77 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
ec163f2
to
b6d0e4a
Compare
@@ -184,11 +213,11 @@ func (r *ClusterExtensionReconciler) handleResolutionErrors(ext *ocv1alpha1.Clus | |||
if errors.As(err, &aggErrs) { | |||
for _, err := range aggErrs.Errors() { | |||
errorMessage := err.Error() | |||
if strings.Contains(errorMessage, "no package") { | |||
if errors.As(err, &NoPackageError{}) { |
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.
Are you able to verify that this works as expected? IIRC, the last time I did something like this I discovered it did not work as expected and had to do it this way: https://github.com/operator-framework/catalogd/blob/fa4a29bae42a5725d932b1bf6c31381f185e99f7/pkg/controllers/core/clustercatalog_controller.go#L79-L82
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.
Semi-off topic, but @everettraven, that recoverable error thing is a feature built directly into controller-runtime since 0.15: https://github.com/kubernetes-sigs/controller-runtime/blob/735b6073bb253c0449bfcf6641855dcf2118bb15/pkg/reconcile/reconcile.go#L105-L109
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.
This PR doesn't contain the whole diff related to error handling and I can't comment on the relevant lines. But I'll try to do my best to explain why I think error handling should be changed.
TL;DR: Opaque errors should do the job here.
The need for custom error types seems to arise from handleResolutionErrors
which for some reason attempts to distinguish between different errors. I do not think there is no need to handle errors separately:
- All branches in
handleResolutionErrors
seem to boil down to the same call:And some variation of the following (only the reason is different):setResolvedStatusConditionFailed(&ext.Status.Conditions, errorMessage, ext.Generation)
ensureAllConditionsWithReason(ext, "ResolutionFailed", errorMessage)
- First two branches (
NoPackageError
andInvalidVersionRangeError
) are the same and set reason toResolutionFailed
. - Last two branches (one handling non-
NoPackageError
and non-InvalidVersionRangeError
errors and one handling non-Aggregate
errors) are also identical and set reason toInstallationStatusUnknown
. - I think
InstallationStatusUnknown
should not be used here since we are handling errors related to the resolution. I believe it is reasonable to always useResolutionFailed
.
Above leaves us with just the following:
setResolvedStatusConditionFailed(&ext.Status.Conditions, errorMessage, ext.Generation)
ensureAllConditionsWithReason(ext, ocv1alpha1.ReasonResolutionFailed, errorMessage)
If we do that we do not need custom error types.
I also have doubts about ensureAllConditionsWithReason
: we only use it in handleResolutionErrors
and do not seem to use this approach consistently (approach of setting all missing conditions to the same reason & message).
I think all of this can be done like this:
bundle, err := r.resolve(ctx, *ext)
if err != nil {
setResolvedStatusConditionFailed(&ext.Status.Conditions, err.Error(), ext.Generation)
// setInstalledStatusConditionFailed, and other relevant conditions
// in the same way we do after r.resolve(ctx, *ext) call.
return ctrl.Result{}, err
}
// Somewhere at the end of reconcile deal with "missing" conditions (instead of using ensureAllConditionsWithReason in place)
// Handle no package found errors, potentially setting status conditions | ||
setResolvedStatusConditionFailed(&ext.Status.Conditions, errorMessage, ext.Generation) | ||
ensureAllConditionsWithReason(ext, "ResolutionFailed", errorMessage) | ||
} else if strings.Contains(errorMessage, "invalid version range") { | ||
} else if errors.As(err, &InvalidVersionRangeError{}) { |
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.
Why is it important to distinguish between different errors here? Why do we need custom error types?
Handling of NoPackageError
and InvalidVersionRangeError
is literally the same.
@m1kola (github doesn't support comment threads), I do believe we need to distinguish between Resolution errors, which likely involve errors in the |
26550da
to
5cfe589
Compare
PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
✅ Deploy Preview for olmv1 ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@tmshort How I see it:
In all the these cases we can fail resolution condition and write error into the condition message. I don't think that setting reason to There is a chance that I'm missing something (e.g. maybe you expect programmatic clients to take advantage of a distinct combination of reasons and take some action?). Happy to discuss it further here or jump on a quick call if you like. |
@ankitathomas's PR is super relevant to the discussion of temporal/transient vs permanent. #842 I think the |
Non-resolution (e.g. timeout) errors can occur in This is just trying to clean up error processing. It's not meant to clean up the status conditions (but it has to do something with status conditions). It looks as though #842 changed title, so it's doing something different now, issue #880 is meant to clean up the status conditions. The hope is that we can have smaller changes (which is why I'm trying to keep this small). |
This PR is focused on removing the string checks for error types, and all the aggregated errors that were being used - issues noted in the big Helm PR #846. It was not meant to fix all the problems with status conditions. |
Separate out resolution errors from generic errors. Signed-off-by: Todd Short <[email protected]>
Signed-off-by: Todd Short <[email protected]>
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.
Love removing code. Looks good to me.
841db34
Description
Reviewer Checklist