[bump_20.10 backport ]Fix panic in agent#3032
Open
thaJeztah wants to merge 1 commit intomoby:bump_20.10from
Open
[bump_20.10 backport ]Fix panic in agent#3032thaJeztah wants to merge 1 commit intomoby:bump_20.10from
thaJeztah wants to merge 1 commit intomoby:bump_20.10from
Conversation
Previously, there was an issue where the agent could panic while attempting to determine if an error was temporary. Before the change, in `agent/exec/errors.go`, the function `IsTemporary` attempted to drill down to a root cause by iterating through the causes of an error by calling `errors.Cause`. If an error has no cause, then `errors.Cause` returns that same error. The issue is that somewhere in the depths of some code, it was posssible for the error to have an underlying type that was non-comparable; for example, maps and slices are uncomparable types. This would cause a panic, as the uncomparable type cannot be compared even to itself. However, one can see that `errors.Cause` has its own loop, and drills down to the root cause in its own way. There is no need for us to iterate here. Instead, we can just take a look at the error itself, and then take a look at its cause once. If neither is temporary, the error is not temporary, and we have nothing to worry about. Signed-off-by: Drew Erny <derny@mirantis.com> (cherry picked from commit 39a4233) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Member
Author
|
@dperny PTAL |
Codecov Report
@@ Coverage Diff @@
## bump_20.10 #3032 +/- ##
==============================================
+ Coverage 61.89% 61.91% +0.01%
==============================================
Files 142 142
Lines 23031 23029 -2
==============================================
+ Hits 14256 14258 +2
+ Misses 7284 7277 -7
- Partials 1491 1494 +3 |
thaJeztah
commented
Oct 27, 2021
| if cause == err { | ||
| break | ||
| } | ||
| cause := errors.Cause(err) |
Member
Author
There was a problem hiding this comment.
Actually; wondering if we should replace this function to use errors.As(). which should be compatible with both errors.Wrap() (github.com/pkg/errors) and native go 1.13 %w wrapping;
// IsTemporary returns true if the error or a recursive cause returns true for
// temporary.
func IsTemporary(err error) bool {
var tmp Temporary
if errors.As(err, &tmp) {
return tmp.Temporary()
}
return false
}See https://play.golang.org/p/tG1klGjjS8R
Details
package main
import (
"fmt"
"github.com/pkg/errors"
)
func main() {
err := fmt.Errorf("hello")
err1 := temporary{fmt.Errorf("hello1: %w", err)}
err2 := errors.Wrap(err1, "hello2")
err3 := errors.Wrap(err2, "hello3")
err4 := fmt.Errorf("hello4: %w", err3)
err5 := fmt.Errorf("hello5: %w", err4)
yeah := IsTemporary(nil)
fmt.Println(yeah)
yeah = IsTemporary(err)
fmt.Println(yeah)
yeah = IsTemporary(err5)
fmt.Println(yeah)
}
// Temporary indicates whether or not the error condition is temporary.
//
// If this is encountered in the controller, the failing operation will be
// retried when this returns true. Otherwise, the operation is considered
// fatal.
type Temporary interface {
Temporary() bool
}
type temporary struct {
error
}
func (t temporary) Cause() error { return t.error }
func (t temporary) Temporary() bool { return true }
// IsTemporary returns true if the error or a recursive cause returns true for
// temporary.
func IsTemporary(err error) bool {
var tmp Temporary
if errors.As(err, &tmp) {
return tmp.Temporary()
}
return false
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
backport of #3024 for 20.10 (already back ported to 19.03 through #3031)
Previously, there was an issue where the agent could panic while
attempting to determine if an error was temporary.
Before the change, in
agent/exec/errors.go, the functionIsTemporaryattempted to drill down to a root cause by iterating through the causes
of an error by calling
errors.Cause. If an error has no cause, thenerrors.Causereturns that same error.The issue is that somewhere in the depths of some code, it was posssible
for the error to have an underlying type that was non-comparable; for
example, maps and slices are uncomparable types. This would cause a
panic, as the uncomparable type cannot be compared even to itself.
However, one can see that
errors.Causehas its own loop, and drillsdown to the root cause in its own way. There is no need for us to
iterate here.
Instead, we can just take a look at the error itself, and then take a
look at its cause once. If neither is temporary, the error is not
temporary, and we have nothing to worry about.
Signed-off-by: Drew Erny derny@mirantis.com
(cherry picked from commit 39a4233)
Signed-off-by: Sebastiaan van Stijn github@gone.nl
- What I did
- How I did it
- How to test it
- Description for the changelog