-
Notifications
You must be signed in to change notification settings - Fork 132
POC: use k8s validation-gen #389
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ import ( | |
| "google.golang.org/grpc/metadata" | ||
| "google.golang.org/grpc/status" | ||
| "google.golang.org/protobuf/proto" | ||
| "google.golang.org/protobuf/protoadapt" | ||
| "google.golang.org/protobuf/reflect/protoreflect" | ||
| ) | ||
|
|
||
|
|
@@ -61,7 +62,23 @@ func ServerUnaryInterceptor(ctx context.Context, req any, info *grpc.UnaryServer | |
|
|
||
| if errors.As(err, &statusErr) { | ||
| st := statusErr.GRPCStatus() | ||
| return nil, status.Error(st.Code(), st.Message()) | ||
| //FIXME: investigate why we are doing this error deconstruction | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not 100% sure why this is here. It looks like it has the effect of sanitizing internal details from the response by unwrapping the error? But then it could just return the unwrapped error directly and avoid copying details. Also, if that's the goal, then returning the raw error at the bottom still can leak internals. Git blame shows Taahir Ahmed (@ahmedtd) as committer, adding him in case there is a Chesterton's Fence issue. |
||
| result := status.New(st.Code(), st.Message()) | ||
|
|
||
| origDetails := st.Details() | ||
| v1Details := make([]protoadapt.MessageV1, 0, len(origDetails)) | ||
| for _, d := range origDetails { | ||
| if msg, ok := d.(protoadapt.MessageV2); ok { | ||
| v1Details = append(v1Details, protoadapt.MessageV1Of(msg)) | ||
| } else { | ||
| return nil, status.Errorf(codes.Internal, "internal error saving error details: not a protoadapt.MessageV2") | ||
| } | ||
| } | ||
| result, err := result.WithDetails(v1Details...) | ||
| if err != nil { | ||
| return nil, status.Errorf(codes.Internal, "internal error saving error details: %v", err) | ||
| } | ||
| return nil, result.Err() | ||
| } | ||
|
|
||
| // No status error found in chain. | ||
|
|
||
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 actually like having a test here for validation as it not only asserts that the validator works, but also that the gRPC server (as we whole) is propagating the Go error to the right gRPC status response.
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 ACK the value of complete testing, but also point out that doing rigorous-but-not-brittle testing requires things like something like "origin" which really shouldn't be part of the user-facing API but is fine for internal API.
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.
How about we move all the exhaustive test cases next to the proto / validate methods, and make it assert on the full (type, field, detail, origin) tuple, but then scope down
ValidationError(or the AIP equivalentFieldViolation1) to what we actually want to put on the write (I assume origin, for example, is not meant to be part of the API contract). Then we have a thin layer of tests here just to make sure we properly map validation errors to gRPC status.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 seems plausible. I added ValidationError because FieldValidation could not carry origin.