Open threesquared opened 7 months ago
First, instead of using a io.TeeReader
, just read the request body into the buffer, then perform data validation and only then, if no error occurs, unmarshal the JSON bytes into the input
object.
Something like this:
decodeJSONBody(readJSON func(rd io.Reader, v interface{}) error, tolerateFormData bool) valueDecoderFunc {
// ...
var b *bytes.Buffer
b = bufPool.Get().(*bytes.Buffer) //nolint:errcheck // bufPool is configured to provide *bytes.Buffer.
defer bufPool.Put(b)
b.Reset()
// First read body into buffer.
if _, err := b.ReadFrom(r.Body); err != nil {
return err
}
validate := validator != nil && validator.HasConstraints(rest.ParamInBody)
if validate {
// Perform validation before unmarshalling into input object.
err := validator.ValidateJSONBody(b.Bytes())
if err != nil {
return err
}
}
return readJSON(b, input)
}
Then you can get the desired result, for example:
{
"status": "INVALID_ARGUMENT",
"error": "invalid argument: validation failed",
"context": {
"body": [
"#/name: expected string, but got number"
]
}
}
Edit: messed up on my end :) This change seems to make it work.
Describe the bug
When validating an input with an incorrect type we get an
failed to decode json: json: cannot unmarshall...
error instead of avalidation failed
error with acontext
object pointing to the issue. This is because the un-marshalling fails before the validator is even run.To Reproduce
Expected behavior
I would expect a type mismatch issue to be reported in the same way as any other validation error to the end user