Giter Club home page Giter Club logo

Comments (4)

migmartri avatar migmartri commented on July 18, 2024
{
  "schemaVersion": "v1",
  "materials": [
    {
      "type": "CONTAINER_IMAGE",
      "name": "skynet-control-plane",
      "output": true,
      "annotations": [
        {
          "name": "component",
          "value": "control-plane"
        },
        {
          "name": "asset"
        }
      ]
    },
    { "type:": "ARTIFACT", "name": "rootfs" },
  ]
}

from chainloop.

javirln avatar javirln commented on July 18, 2024

Doing a research on the topic I've found the following:

  • Both the grpcurl and the CLI start from the same state, need to convert from a json to a proto structure. Such conversation is the one that is raising the error unknown field "type:".
  • Server side validation using a grpc client work in a different way. From typescript, the value is being transformed to whatever the proto definition says and ignores unknown types. That ignoring of unknown types mean that when passing a type: on that material the actual type would be of type type: MATERIAL_TYPE_UNSPECIFIED which is the default value of the enum.
  • protovalidate has a nice feature where you can skip on the middleware the validation of certain messages doing the following change, which will leave the validation to the developer in a later stage.
diff --git a/app/controlplane/internal/server/grpc.go b/app/controlplane/internal/server/grpc.go
index 5754ff3..ec4a610 100644
--- a/app/controlplane/internal/server/grpc.go
+++ b/app/controlplane/internal/server/grpc.go
@@ -97,7 +97,11 @@ func NewGRPCServer(opts *Opts) (*grpc.Server, error) {
 		grpc.Middleware(craftMiddleware(opts)...),
 		grpc.UnaryInterceptor(
 			grpc_prometheus.UnaryServerInterceptor,
-			protovalidateMiddleware.UnaryServerInterceptor(opts.Validator),
+			protovalidateMiddleware.UnaryServerInterceptor(opts.Validator,
+				// Any message that is registered here will not be validated, therefore, validation
+				// must happen somewhere else, proceed with caution
+				protovalidateMiddleware.WithIgnoreMessages((&v1.WorkflowContractServiceCreateRequest{}).ProtoReflect().Type()),
+			),
 		),
 	}
 

What this means is that, when reaching the server, the validations are run thanks to protovalidate and raise validation error: - v1.materials[4].type: value must not be in list [0] [enum.not_in] and this is because the incoming proto although well formed is not valid upon our constraints.

We cannot perform the same operation as the CLI does under the hood since what is received on the server is correct although not valid so going from proto => json => proto won't work because the type would still be type: MATERIAL_TYPE_UNSPECIFIED, if we later run the validation, then we will fail.

The solution then, would be on the approach of improving the error message. Unfortunately the buf validation library although wide, does not provide much more configuration except the cel option:

Something like this will perform in the same way as the enum validation we have in place. From here:

    MaterialType type = 1 [
      (buf.validate.field).enum = {
        not_in: [0]
      },
      (buf.validate.field).enum.defined_only = true
    ];

To here:

    MaterialType type = 1 [(buf.validate.field).cel = {
      id: "type"
      message: "Type must be one of the allowed values"
      expression: "this != 0 && this in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]"
    }];

As you can see one of the drawback is, that we need to keep track of the list of values.

To sum up, we need to find a way of improving the general return of errors in the API level.

from chainloop.

danlishka avatar danlishka commented on July 18, 2024

what are the next steps on this then?

from chainloop.

migmartri avatar migmartri commented on July 18, 2024

I'd like to double check the possibility of improving validation error messages server side. It's very discouraging that at first this is not trivial. So next step is to look into how hard is to have custom error messages applied to the proto validations.

from chainloop.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.