sdk-go icon indicating copy to clipboard operation
sdk-go copied to clipboard

Feature request: disable event validation

Open binczyk opened this issue 3 years ago • 3 comments

Let's say that I would like to handle invalid events that do not conform with specification in my own receiver function. Is it possible to add a feature toggle to disable validation in Invoke?

// Check if event is valid before invoking the receiver function
if e != nil {
    if validationErr := e.Validate(); validationErr != nil {
        r.observabilityService.RecordReceivedMalformedEvent(ctx, validationErr)
	return respFn(ctx, nil, protocol.NewReceipt(false, "validation error in incoming event: %w", validationErr))
    }
}

The problem I'm trying to solve is to send ack even for invalid events received from kafka.

binczyk avatar Feb 15 '22 08:02 binczyk

I see two ways to go about this,

1- use the bindings and protocol directly without the client.

2- There used to be a way to recover from malformed events, it was a function you would register with the client and you could return back a correctly formatted event or nil and it would do what you want: ack the upstream.

Which of these options would best solve your problem? I am not sure it is a great idea to allow the validation to be turned off in the client, but if there is a compelling enough use-case I could be convinced. (guess this is option 3 as the issue suggests)

n3wscott avatar Feb 15 '22 23:02 n3wscott

Is there any example how to implement the second option?

Thanks

binczyk avatar Feb 17 '22 09:02 binczyk

Came here with a similar issue. I have a client that uses the http protocol to receive cloudevents from a pubsub push. (I have a custom Format to handle the "application/json" that pub-sub sends.)

If any kind of malformed event gets into the pubsub topic, and my format.Unmarshal() returns an error, cloud run reports a 500, but pubsub will continue to send it infinitely. It's hard to trace exactly where Unmarshal gets called in the receive loop, but I'm presuming it's in binding.ToEvent(), which I think happens just before event validation.

I actually wonder whether a message that fails event parsing or validation should ever do anything other than NACK, because definitionally, it can't be handled. I actually thought that's what the current code was doing when it responds with protocol.NewReceipt(false, "failed to convert Message to Event: %w", eventErr), but apparently not?

(I guess there are cases where you could potentially redeploy and be in a position to handle them later, if it was not the message that was malformed, but the parser 🤷🏼 .)

I'd like to continue using the client, which provides a simpler way of interacting with inbound events. And, I like that the validation exists. But, I too would love an option to recover from a malformed event.

I'm happy to do a user-defined method that returns nil. I'd also be happy with a client option that automatically NACK'd failed event parsing or validation. That seems a bit safer than allowing to be turned off entirely?

majelbstoat avatar Apr 03 '22 04:04 majelbstoat