-
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
*: demonstrate uses of the errors library #38127
Conversation
Last comments from @andreimatei I've looked at those 3 commits.
pkg/cli/sql.go, line 1479 at r28 (raw file):
I was gonna ask if this method could stop using pkg/sql/distsqlpb/data.go, line 149 at r28 (raw file):
consider gating this code on a cluster version check for pkg/sql/distsqlpb/data.go, line 171 at r28 (raw file):
you mean 19.2 here I think pkg/sql/distsqlpb/data.proto, line 58 at r28 (raw file):
writing this field must have been satisfying :) pkg/sql/pgwire/pgerror/errors.proto, line 52 at r28 (raw file):
nit: just say "TODO: remove in 19.3" here and elsewhere |
More comments from @andreimatei
pkg/sql/schema_changer.go, line 195 at r26 (raw file):
Have you considered doing gating the use of pkg/sql/schema_changer.go, line 219 at r26 (raw file):
Why not pkg/sql/schema_changer.go, line 840 at r26 (raw file):
do we still need the logging above if we're doing pkg/sql/schema_changer.go, line 865 at r26 (raw file):
same about the logging above |
Last comments from @RaduBerinde
It's not a big deal if it's not easy. One idea would be to use By the way - Another thing - when looking through the WithXX functions available, it was hard to understand whether the info I'm adding would be visible if you just print the error (in general, it's hard to know how the info would show up in various contexts, like printing or going over pgwire). It would be good to add to the comments for these. |
1aa4eec
to
02c808e
Compare
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.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/schema_changer.go, line 197 at r12 (raw file):
Have you considered doing gating the use of errors.Is() here on a cluster version check? That'll remind us to remove the old code next release.
Yes I have considered, however there are more places that test this particular error in this way. Filed #38128 to address them comprehensively.
pkg/sql/schema_changer.go, line 218 at r12 (raw file):
Why not errors.Is() here?
Please put more words in this comment; as written I don't think it'll mean much to people (it doesn't even mean much to me :P)
Good idea. Done. Also, removed the comment.
pkg/sql/schema_changer.go, line 837 at r12 (raw file):
do we still need the logging above if we're doing RecordError()? Seems to me that RecordError could log if it doesn't already.
RecordError
only logs (with log.Error
) when the error is an internal (assertion) error.
This logging here ensures that any error in the schema changer gets logged as a warning.
pkg/sql/schema_changer.go, line 865 at r12 (raw file):
same about the logging above
ditto
pkg/sql/distsqlpb/data.go, line 149 at r13 (raw file):
consider gating this code on a cluster version check for 19.2
I like the idea (and doing it in other places), however here it's not possible because this is also called from a String()
method which does not have access to the cluster version.
pkg/sql/distsqlpb/data.go, line 171 at r13 (raw file):
you mean 19.2 here I think
yes I did, thanks. Fixed.
pkg/sql/pgwire/pgerror/errors.proto, line 52 at r13 (raw file):
nit: just say "TODO: remove in 19.3" here and elsewhere
Done.
We already do this (at the end of
I do not understand this. I have tried manually to use it and I do not see what you see. can you tell more?
Agreed - this merits a summary in the RFC. I think this table will help:
|
11ef5d4
to
e1a2ffc
Compare
e1a2ffc
to
bf152aa
Compare
bf152aa
to
ef803ab
Compare
Try this diff: --- a/pkg/sql/parser/lexer.go
+++ b/pkg/sql/parser/lexer.go
@@ -194,7 +194,8 @@ func (l *lexer) populateErrorDetails() {
// parser encounters a parsing error.
l.lastError = errors.Wrap(l.lastError, "syntax error")
}
- l.lastError = errors.Wrapf(l.lastError, "at or near \"%s\"", lastTok.str)
+ l.lastError = errors.WithDetailf(l.lastError, "at or near \"%s\"", lastTok.str)
} Then run
It would be great if we included this information for each // WithDetail decorates an error with a textual detail.
// The detail may contain PII and thus will not reportable.
-// Note: the detail does not appear in the main error message
-// returned with Error().
+//
+// Visibility of the detail:
+// - Error(): not visible
+// - %+v: visible (on subsequent lines)
+// - pgwire: detail payload
+// |
... since the error library's Wrap is decent enough. Release note: None
Release note: None
Release note: None
The new function `Flatten()` provides the bridge between the new error library on the remainder of the code using pgerror.Error. Release note: None
…rors Release note: None
Release note: None
This replaces code that mutates `pgerror.Error` objects in place by code that adds hints and detail annotations agnostic of the particular error type. Release note: None
Release note: None
Prior to this patch, the opt code was special-casing pgerror.Error and required an object of this type to be present in the causal chain to work properly. This patch removes the requirement by using the facilities from the errors library. Release note: None
Release note: None
Release note: None
`GetPGCause()` is annoying/counter-productive because it peels all the decorations around a `pgerror.Error`, including details that may be helpful to troubleshooting. It is also not friendly to the new errors library which is able to define pg error code without using `pgerror.Error`. This patch removes all its uses but one (last remaining in `distsqlpb`, modified in a later patch) and replaces them, when applicable, by `GetPGCode()` which is friendly to the new errors library. Release note: None
This patch introduces support for receiving decorated (non-`pgerror.Error`) errors from distsql flows. It also redefines the `pgerror` helpers to use the new errors library, so as to not instantiate `pgerror.Error` object until/unless `Flatten()` is called. This way errors remain as regular errors (and not `pgerror.Error`) throughout most of the CockroachDB internals, and only become `pgerror.Error` ("flattened") at very few points: - to generate a compatibility payload when sending an error to 19.1 nodes - in pgwire to generate packets for clients - in the output of SHOW SYNTAX - in some tests Release note: None
Release note: None
Release note: None
A while ago I had changed many calls to `errors.Errorf`/`errors.New`/`fmt.Errorf`/`errors.Wrap` to use `pgerror` error constructors instead. The goal was to ensure the error objects were decorated with safe details suitable for reporting. However using those APIs also required a pg error code, even in cases where none was obviously available. So I chose then to use the pg code "CodeDataException" as a dummy value. Now that the `errors` library is able to annotate errors in all the good ways, the `pgerror` interface is not needed any more. This commit reverts the past change. This change is nearly all mechanical, using perl. The only manual change is to the function `wrapRowErr` in the `importccl` package. Release note: None
... instead of the aliased definitions in `pgerror`. (This change is entirely mechanical, using perl) Release note: None
Release note: None
... where appropriate. This drops the dependency on `util/log` in many cases. (This change was mechanical, using perl) Release note: None
... and remove pgwire/pgerror/codes.go Release note: None
Previously `teamcity-testrace.sh` would run `testrace` passing all the modified packages simultaneously in the PKG make var. This causes `go test` to issue all the tests concurrently, regardless of available hardware. If there are sufficiently many packages modified, this overloads the machines, makes test run much slower than usual, and triggers bad behavior (timeouts). This patch alleviates the potential problem by running the tests one after the other. Release note: None
684b49b
to
dc13807
Compare
37121: errors: introduce a general-purpose modular error library with good properties r=knz a=knz This PR introduces an error library implemented after the principles laid out in #36987. It subsumes the following two PRs: - #38127 *: demonstrate uses of the errors library - review approval: #38127 (comment) - #37813 sql, *: simplify remove dependencies on pgerror, util/log - review approval: #37813 (comment) Release note: None Co-authored-by: Raphael 'kena' Poss <[email protected]>
sql, *: simplify remove dependencies on pgerror, util/log
This continues the discussion from #37765 - the original PR was auto-closed by github (due to a bug?) so I opened this new PR.
This PR adapts various places in CockroachDB to demonstrate benefits of the errors library introduced in #36987 / #37121.
The main goals of this PR is to remove most usages of
pgerror.Error
, and replace them by regular error objects.The benefit of this change is that all errors details are then preserved throughout distsql execution.
This is achieved by the following high level steps:
the introduction of a new function
pgerror.Flatten()
that can convert a regular error into a*pgerror.Error
.This step occurs in a commit in the PR near the beginning, called "
pgerror: add Flatten() to convert errors into pgerror.Error
"This function is meant to be used at "boundaries" only:
changing the implementation of the
pgerror.XXX()
constructor functions to use the new library's constructors instead.This step is achieved by another commit in the PR near the end, called "
pgwire, distsqlpb: let native errors flow through
"From that point, most of the in-flight error objects inside CockroachDB are not instances of
pgerror.Error
any more.(The exception is a pgerror.Error object received on a distsql flow from a v19.1 node).
This is thus also the moment where calls to
pgerror.Flatten()
really become necessary at the aforementioned boundaries.The end result is that most of the "interior" of CockroachDB sees plain error objects and cannot expect a
*pgerror.Error
object any more.The remaining commits in this PR are necessary to make these thing work together well:
the few commits towards the beginning, prior to step 1 are ancillary commits that ensure that SQL errors are produced where appropriate.
(two actually belong to other PRs sql/row: use assertion failures instead of panics #37802 sem/tree: avoid deconstructing the error when parsing a datum #37806 and will disappear when those PRs are merged)
the commits in-between steps 1 and 2 changes the "interior" code to not rely on the presence of a
pgerror.Error
object in the causal chain.These commits must occur after step 1 because they require the presence of a "pg error code" which is computed by
Flatten()
's companion functionGetPGCode()
.the commits after step 2 are mostly cosmetic and remove more dependencies on pgerror.Error in other places.