Skip to content

Support nested body params for CompositeError #2594

@veleek

Description

@veleek

Problem statement

If you create a spec that has a complex nested body parameter. The validation logic will return errors.CompositeError instead of errors.Validation. As a result, the nested error messages don't get adjusted with the nested field name making it impossible to differentiate from errors that are returned from the root object and those returned by the nested object.

Here's an example of the generated validation logic.

func (m *CreateRequest) validatePlayer(formats strfmt.Registry) error {
	if m.Player != nil {
		if err := m.Player.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("player")
			}
			return err
		}
	}

	return nil
}

func (m *Player) Validate(formats strfmt.Registry) error {
	var res []error

	if err := m.validateLastUpdated(formats); err != nil {
		res = append(res, err)
	}

	if len(res) > 0 {
		return errors.CompositeValidationError(res...)
	}
	return nil
}

If the parent object has a property with the same name as the child (LastUpdated in the example below), it will return an error saying lastUpdated in body must be of type date-time or similar for both an error on CreateRequest.LastUpdated and CreateRequest.Player.LastUpdated.

The generated validation logic should be updated to support CompositeErrors. There are a few ways to accomplish this:

  1. Add some inline logic for calling ValidateName on each errors.Validation in a CompositeError
  2. Update errors.CompositeError to have an implementation of ValidateName and call it.
  3. Create a ValidationNamer interface that both CompositeError and Validation implement and then call that here (simplifies the logic but still needs Add a Gitter chat badge to README.md #2 above implemented).

Swagger specification

{
  "swagger": "2.0",
  "info": {
    "title": "Sample",
    "version": "v1"
  },
  "paths": {},
  "definitions": {
    "CreateRequest": {
      "properties": {
        "lastUpdated": {
          "format": "date-time",
          "type": "string"
        }
        "player": {
          "$ref": "#/definitions/Player"
        }
      },
      "type": "object"
    },
    "Player": {
      "properties": {
        "lastUpdated": {
          "format": "date-time",
          "type": "string"
        }
      },
      "type": "object"
    }
  },
  "x-components": {}
}

Steps to reproduce

  1. Create a spec with a nested param that returns a CompositeError from its Validate method.
  2. Generate client code and verify the validation logic for nested properties.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions