-
Notifications
You must be signed in to change notification settings - Fork 801
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
Wrap underlying cause for conditional update error #4797
Conversation
service/history/execution/context.go
Outdated
} | ||
|
||
func (e *conflictError) Error() string { | ||
return fmt.Sprintf("conditional update failed: %s", e.Cause.Error()) |
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.
return fmt.Sprintf("conditional update failed: %s", e.Cause.Error()) | |
return fmt.Sprintf("conditional update failed: %v", e.Cause) |
Since I haven't actually looked into it in detail before: this should probably be ... %v", e.Cause
.
Because:
fmt.Errorf
does this: https://github.com/golang/go/blob/master/src/fmt/errors.go#L17-L30
and, with the Error()
impl which just returns that message, is basically "eagerly create the full message".
TIL.
That wrapErrs
flag later reaches here in the fmt printer: https://github.com/golang/go/blob/master/src/fmt/print.go#L574-L587
which just swaps it with %v
for stringifying, and holds onto the error value (which is ignored by Errorf).
TIL 2.
That's... simple and fairly backwards-compatible, but yow. Worse than I expected. Potentially unnecessarily costly and destroys a lot of information for no good reason (doesn't check for or support %+v
or %#v
because it can't).
service/history/execution/context.go
Outdated
// NewConflictError is only public because it used in workflow/util_test.go | ||
// TODO: refactor those tests | ||
func NewConflictError(cause error) error { | ||
return &conflictError{cause} | ||
} |
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.
personal preference: require a *testing.T
argument for any test-only code. even if it's unused, it makes it rather unambiguous that it's not intended for any other kind of use.
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.
That is actually a neat idea 👍 . I'm going to do that from now on.
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.
Small stuff worth thinking about, but LGTM.
Hiding the value (and type if feasible) and using an IsThing
func is definitely my personal preference - it's more future-flexible and you can't miss any of the old references, so 👍👍
Pull Request Test Coverage Report for Build edaf25ea-7de7-4406-b49d-7e057268957c
💛 - Coveralls |
What changed?
Instead of using value error
execution.ErrConflict
lets use error typeexecution.conflictError
which wraps underlying cause.Why?
Currently it can be very hard to debug certain failures when only thing that is visible in logs or returned via some endpoints is
code:internal message:conditional update failed
Now, underlying cause will be included in error message as well.
How did you test it?
Potential risks
Release notes
Documentation Changes