func generateErrorMessages(serviceMap RawServiceMap, schema map[string]interface{}, result *gojsonschema.Result) error {
	var validationErrors []string

	// gojsonschema can create extraneous "additional_property_not_allowed" errors in some cases
	// If this is set, and the error is at root level, skip over that error
	skipRootAdditionalPropertyError := false

	if !result.Valid() {
		for i := 0; i < len(result.Errors()); i++ {
			err := result.Errors()[i]

			if skipRootAdditionalPropertyError && err.Type() == "additional_property_not_allowed" && err.Context().String() == "(root)" {
				skipRootAdditionalPropertyError = false
				continue
			}

			if err.Context().String() == "(root)" {
				switch err.Type() {
				case "additional_property_not_allowed":
					validationErrors = append(validationErrors, fmt.Sprintf("Invalid service name '%s' - only [a-zA-Z0-9\\._\\-] characters are allowed", err.Field()))
				default:
					validationErrors = append(validationErrors, err.Description())
				}
			} else {
				skipRootAdditionalPropertyError = true

				serviceName := serviceNameFromErrorField(err.Field())
				key := keyNameFromErrorField(err.Field())

				switch err.Type() {
				case "additional_property_not_allowed":
					validationErrors = append(validationErrors, unsupportedConfigMessage(key, result.Errors()[i+1]))
				case "number_one_of":
					validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' configuration key '%s' %s", serviceName, key, oneOfMessage(serviceMap, schema, err, result.Errors()[i+1])))

					// Next error handled in oneOfMessage, skip over it
					i++
				case "invalid_type":
					validationErrors = append(validationErrors, invalidTypeMessage(serviceName, key, err))
				case "required":
					validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' option '%s' is invalid, %s", serviceName, key, err.Description()))
				case "missing_dependency":
					dependency := err.Details()["dependency"].(string)
					validationErrors = append(validationErrors, fmt.Sprintf("Invalid configuration for '%s' service: dependency '%s' is not satisfied", serviceName, dependency))
				case "unique":
					contextWithDuplicates := getValue(serviceMap, err.Context().String())
					validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' configuration key '%s' value %s has non-unique elements", serviceName, key, contextWithDuplicates))
				default:
					validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' configuration key %s value %s", serviceName, key, err.Description()))
				}
			}
		}

		return fmt.Errorf(strings.Join(validationErrors, "\n"))
	}

	return nil
}
Exemple #2
0
func toError(result *gojsonschema.Result) error {
	err := getMostSpecificError(result.Errors())
	description := getDescription(err)
	return fmt.Errorf("%s %s", err.Field(), description)
}