Skip to content

Commit

Permalink
V3: Add better message on validator
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre-Emmanuel Jacquier <15922119+pierre-emmanuelJ@users.noreply.github.com>
  • Loading branch information
pierre-emmanuelJ committed Jan 23, 2024
1 parent 1ace995 commit 986223b
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
27 changes: 25 additions & 2 deletions v3/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,31 @@ func Ptr[T any](v T) *T {
}

// Validate any struct from schema or request
func Validate(r any) error {
return validator.New().Struct(r)
func (c Client) Validate(s any) error {
err := c.validate.Struct(s)
if err == nil {
return nil
}

// Print better error messages
validationErrors := err.(validator.ValidationErrors)

if len(validationErrors) > 0 {
e := validationErrors[0]
errorString := fmt.Sprintf(
"Request validation error: '%s' = '%v' does not validate ",
e.StructNamespace(),
e.Value(),
)
if e.Param() == "" {
errorString += fmt.Sprintf("'%s'", e.ActualTag())
} else {
errorString += fmt.Sprintf("'%s=%v'", e.ActualTag(), e.Param())
}
return fmt.Errorf(errorString)
}

return err
}

func prepareJSONBody(body any) (*bytes.Reader, error) {
Expand Down
15 changes: 15 additions & 0 deletions v3/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions v3/generator/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func Generate(doc libopenapi.Document, path, packageName string) error {
"errors"
"github.com/exoscale/egoscale/version"
"github.com/go-playground/validator/v10"
)
`, packageName))

Expand Down
56 changes: 35 additions & 21 deletions v3/generator/client/client.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Client struct {
httpClient *http.Client
timeout time.Duration
pollingInterval time.Duration
validate *validator.Validate
trace bool

// A list of callbacks for modifying requests which are generated before sending over
Expand Down Expand Up @@ -71,6 +72,14 @@ func ClientOptWithTrace() ClientOpt {
}
}

// ClientOptWithValidator returns a ClientOpt with a given validator.
func ClientOptWithValidator(validate *validator.Validate) ClientOpt {
return func(c *Client) error {
c.validate = validate
return nil
}
}

// ClientOptWithURL returns a ClientOpt With a given zone URL.
func ClientOptWithURL(url URL) ClientOpt {
return func(c *Client) error {
Expand Down Expand Up @@ -113,6 +122,7 @@ func NewClient(apiKey, apiSecret string, opts ...ClientOpt) (*Client, error) {
serverURL: string({{ .ServerURL }}),
httpClient: http.DefaultClient,
pollingInterval: pollingInterval,
validate: validator.New(),
}

for _, opt := range opts {
Expand All @@ -127,37 +137,40 @@ func NewClient(apiKey, apiSecret string, opts ...ClientOpt) (*Client, error) {
// WithURL returns a copy of Client with new zone URL.
func (c *Client) WithURL(url URL) *Client {
return &Client{
apiKey: c.apiKey,
apiSecret: c.apiSecret,
serverURL: string(url),
httpClient: c.httpClient,
requestInterceptors: c.requestInterceptors,
pollingInterval: c.pollingInterval,
apiKey: c.apiKey,
apiSecret: c.apiSecret,
serverURL: string(url),
httpClient: c.httpClient,
requestInterceptors: c.requestInterceptors,
pollingInterval: c.pollingInterval,
validate: c.validate,
}
}

// WithTrace returns a copy of Client with tracing enabled.
func (c *Client) WithTrace() *Client {
return &Client{
apiKey: c.apiKey,
apiSecret: c.apiSecret,
serverURL: c.serverURL,
httpClient: c.httpClient,
requestInterceptors: c.requestInterceptors,
pollingInterval: c.pollingInterval,
trace: true,
apiKey: c.apiKey,
apiSecret: c.apiSecret,
serverURL: c.serverURL,
httpClient: c.httpClient,
requestInterceptors: c.requestInterceptors,
pollingInterval: c.pollingInterval,
trace: true,
validate: c.validate,
}
}

// WithHttpClient returns a copy of Client with new http.Client.
func (c *Client) WithHttpClient(client *http.Client) *Client {
return &Client{
apiKey: c.apiKey,
apiSecret: c.apiSecret,
serverURL: c.serverURL,
httpClient: client,
requestInterceptors: c.requestInterceptors,
pollingInterval: c.pollingInterval,
apiKey: c.apiKey,
apiSecret: c.apiSecret,
serverURL: c.serverURL,
httpClient: client,
requestInterceptors: c.requestInterceptors,
pollingInterval: c.pollingInterval,
validate: c.validate,
}
}

Expand All @@ -168,8 +181,9 @@ func (c *Client) WithRequestInterceptor(f ...RequestInterceptorFn) *Client {
apiSecret: c.apiSecret,
serverURL: c.serverURL,
httpClient: c.httpClient,
requestInterceptors: append(c.requestInterceptors, f...),
pollingInterval: c.pollingInterval,
requestInterceptors: append(c.requestInterceptors, f...),
pollingInterval: c.pollingInterval,
validate: c.validate,
}
}

Expand Down

0 comments on commit 986223b

Please # to comment.