-
Notifications
You must be signed in to change notification settings - Fork 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
Preventing panics of RecoverableError casts #2267
Conversation
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.
Thanks for jumping on a fix, and I'm sorry for introducing this bug.
I've left some comments that hopefully guide you toward the solution that avoids re-introducing a past bug where nil errors because non-nil errors.
I can also just take this over if you like.
Thanks again!
nomad/structs/structs.go
Outdated
@@ -4054,7 +4054,7 @@ type RecoverableError struct { | |||
|
|||
// NewRecoverableError is used to wrap an error and mark it as recoverable or | |||
// not. | |||
func NewRecoverableError(e error, recoverable bool) error { | |||
func NewRecoverableError(e error, recoverable bool) *RecoverableError { |
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.
So, I changed this return value from *RecoverableError
to error
intentionally in 0.5.3 to avoid turning nil error
s into non-nil *RecoverableError
s. Here's an example of that sort of problem: https://play.golang.org/p/Y8z9GdcAhx
So let's keep returning error here to avoid that issue.
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.
Thanks for the awesome explanation. What a nasty side effect.
nomad/node_endpoint.go
Outdated
@@ -944,7 +944,7 @@ func (n *Node) DeriveVaultToken(args *structs.DeriveVaultTokenRequest, | |||
// setErr is a helper for setting the recoverable error on the reply and | |||
// logging it | |||
setErr := func(e error, recoverable bool) { | |||
reply.Error = structs.NewRecoverableError(e, recoverable).(*structs.RecoverableError) | |||
reply.Error = structs.NewRecoverableError(e, recoverable) |
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.
Instead of omitting the type assertion, let's just check if error is nil and return early.
Otherwise we re-introduce a bug where reply.Error
gets set even when the original error e
was nil!
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.
I was going to do a type assertion before I thought I could just change the return type.
Will have shortly.
@schmichael see latest |
nomad/node_endpoint.go
Outdated
@@ -944,7 +944,9 @@ func (n *Node) DeriveVaultToken(args *structs.DeriveVaultTokenRequest, | |||
// setErr is a helper for setting the recoverable error on the reply and | |||
// logging it | |||
setErr := func(e error, recoverable bool) { | |||
reply.Error = structs.NewRecoverableError(e, recoverable).(*structs.RecoverableError) | |||
if rerr, ok := structs.NewRecoverableError(e, recoverable).(*structs.RecoverableError); ok { |
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 approach will still log an error even when e
is nil.
Instead I would just check if e
is nil and return early:
setErr := func(...) {
if e == nil { return }
// ...existing code...
}
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.
Oh, right. nil
is "castable" to *structs.RecoverableError
.
Just run Thanks for sticking with this! Handling custom errors in Go is sadly tricky. You'll be the third person to try to get all of this logic right. :) |
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.
Only build failures aren't your fault. Merging!
I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions. |
Fixes #2266