package validator import ( "errors" "fmt" "mangezmieux-backend/internal/logger" "mangezmieux-backend/internal/responses" "regexp" "strings" validatorLib "github.com/go-playground/validator/v10" ) var regexpValidatorNamespacePrefix = regexp.MustCompile(`^\w+\.`) func NewDataValidationAPIError(err error) responses.APIError { apiErr := responses.ErrDataValidation if err != nil { var invalidValidationErrror *validatorLib.InvalidValidationError if errors.As(err, &invalidValidationErrror) { logger.GetLogger().WithError(invalidValidationErrror).WithField("templateAPIErr", apiErr).Error("InvalidValidationError") } else { var validationErrors validatorLib.ValidationErrors if errors.As(err, &validationErrors) { for _, e := range validationErrors { reason := e.Tag() if _, ok := CustomValidators[e.Tag()]; ok { reason = truncatingSprintf(CustomValidators[e.Tag()].Message, e.Param()) } namespaceWithoutStructName := regexpValidatorNamespacePrefix.ReplaceAllString(e.Namespace(), "") fe := responses.FieldError{ Field: namespaceWithoutStructName, Constraint: e.Tag(), Description: reason, } apiErr.Details = append(apiErr.Details, fe) } } else { apiErr.Description = err.Error() } } } return apiErr } // truncatingSprintf is used as fmt.Sprintf but allow to truncate the additional parameters given when there is more parameters than %v in str. func truncatingSprintf(str string, args ...interface{}) string { n := strings.Count(str, "%v") return fmt.Sprintf(str, args[:n]...) }