-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
roachpb: remove deprecated fields from Error #73686
Conversation
CRDB 21.2 already populates `Errors.EncodedError`, so we can remove the deprecated fields. I was motivated by this when working on a follow-up to cockroachdb#73602 and ended up trying to marshal an `Error` to JSON, which panics since it ends up trying to use `reflect` to get an unexported value (due to the `customname` tags on the deprecated fields). This behavior persists even with the `json: "-"` tag, by the way, indicating that we should never use `(gogoproto.customname)` to make a field private. It's also just one more papercut that comes with using `gogoproto` but that's a much bigger fish to fry. Release note: None
561e655
to
66c8399
Compare
I typed this up at the end of my day and had to send it out in a bit of a rush, so reviewers should feel comfortable waiting until I've given myself a self-review early next week. This stuff is slightly terrifying, don't want to know what will go wrong if there's a bug in here. |
note for next week: I can also remove another thread that I should pull on: the loss of fidelity in type GoError struct {
wrapped error // corresponds to pErr.EncodedError, we implement stuff for `errors.Is` etc
Index int
// other fields too
}
func (err *GoError) AsProto() *Error {
return &Error{
// populate all fields from `err`
}
} and then func (e *Error) GoError() {
return &GoError{
wrapped: e.decode(),
Index: e.Index,
// ...
}
} func NewError(err error) {
var goErr error
if errors.As(err, &goErr) {
return goErr.AsProto()
}
return &Error{ /* ... */ }
} and here we have it, |
Actually rather than having @knz would appreciate your eyes on the thinking. |
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 think this is a step in the right direction. What are the open questions that remain?
(I'm a little bit confused by roachpb.internalError. What purpose does it serve?)
Reviewed 2 of 4 files at r1, 3 of 3 files at r2, all commit messages.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on @nvanbenschoten and @tbg)
pkg/roachpb/errors.go, line 151 at r2 (raw file):
return nil } if intErr, ok := err.(*internalError); ok {
Can you walk me through the role of internalError
? What is this for? Why does it hide its cause?
pkg/roachpb/errors.go, line 187 at r2 (raw file):
// SafeFormat implements redact.SafeFormatter. func (e *Error) SafeFormat(s redact.SafePrinter, _ rune) {
If/when *Error
is meant to become an error
, you may want to implement errors.SafeFormatter
instead. This may be worth adding a TODO.
pkg/roachpb/errors.go, line 230 at r2 (raw file):
func (e *Error) TransactionRestart() TransactionRestart { var iface transactionRestartError if errors.As(e.decode(), &iface) {
Is there a way to memoize the result of decoding, so we don't end up doing it on every api call that uses .decode()? Decoding is rather expensive.
CRDB 21.2 already populates
Errors.EncodedError
, so we can remove thedeprecated fields.
I was motivated to do this when working on a follow-up to #73602 and
ended up trying to marshal an
Error
to JSON, which panics sinceit ends up trying to use
reflect
to get an unexported value (dueto the
customname
tags on the deprecated fields). This behaviorpersists even with the
json: "-"
tag, by the way, indicatingthat we should never use
(gogoproto.customname)
to make a fieldprivate. It's also just one more papercut that comes with using
gogoproto
but that's a much bigger fish to fry.cc @lidorcarmel since you're just poking at
Error
.Release note: None