You've already forked pocketbase
							
							
				mirror of
				https://github.com/pocketbase/pocketbase.git
				synced 2025-10-31 16:47:43 +02:00 
			
		
		
		
	updated error messages
This commit is contained in:
		| @@ -2,6 +2,8 @@ | ||||
|  | ||||
| - Added `RequestEvent.Blob(status, contentType string, bytes)` response write helper ([#5940](https://github.com/pocketbase/pocketbase/discussions/5940)). | ||||
|  | ||||
| - Added more descriptive error messages. | ||||
|  | ||||
|  | ||||
| ## v0.23.0 | ||||
|  | ||||
|   | ||||
| @@ -175,7 +175,7 @@ type recordOAuth2LoginForm struct { | ||||
|  | ||||
| func (form *recordOAuth2LoginForm) validate() error { | ||||
| 	return validation.ValidateStruct(form, | ||||
| 		validation.Field(&form.Provider, validation.Required, validation.By(form.checkProviderName)), | ||||
| 		validation.Field(&form.Provider, validation.Required, validation.Length(0, 100), validation.By(form.checkProviderName)), | ||||
| 		validation.Field(&form.Code, validation.Required), | ||||
| 		validation.Field(&form.RedirectURL, validation.Required), | ||||
| 	) | ||||
| @@ -186,7 +186,7 @@ func (form *recordOAuth2LoginForm) checkProviderName(value any) error { | ||||
|  | ||||
| 	_, ok := form.collection.OAuth2.GetProviderConfig(name) | ||||
| 	if !ok { | ||||
| 		return validation.NewError("validation_invalid_provider", fmt.Sprintf("Provider with name %q is missing or is not enabled.", name)). | ||||
| 		return validation.NewError("validation_invalid_provider", "Provider with name {{.name}} is missing or is not enabled."). | ||||
| 			SetParams(map[string]any{"name": name}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -445,7 +445,7 @@ func checkForDuplicatedProviders(value any) error { | ||||
| 		if _, ok := existing[c.Name]; ok { | ||||
| 			return validation.Errors{ | ||||
| 				strconv.Itoa(i): validation.Errors{ | ||||
| 					"name": validation.NewError("validation_duplicated_provider", "The provider "+c.Name+" is already registered."). | ||||
| 					"name": validation.NewError("validation_duplicated_provider", "The provider {{.name}} is already registered."). | ||||
| 						SetParams(map[string]any{"name": c.Name}), | ||||
| 				}, | ||||
| 			} | ||||
| @@ -493,7 +493,7 @@ func checkProviderName(value any) error { | ||||
| 	} | ||||
|  | ||||
| 	if _, err := auth.NewProviderByName(name); err != nil { | ||||
| 		return validation.NewError("validation_missing_provider", "Invalid or missing provider with name "+name+"."). | ||||
| 		return validation.NewError("validation_missing_provider", "Invalid or missing provider with name {{.name}}."). | ||||
| 			SetParams(map[string]any{"name": name}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -349,9 +349,7 @@ func createCollectionIndexes(app App, collection *Collection) error { | ||||
| 				errs[strconv.Itoa(i)] = validation.NewError( | ||||
| 					"validation_invalid_index_expression", | ||||
| 					fmt.Sprintf("Failed to create index %s - %v.", parsed.IndexName, err.Error()), | ||||
| 				).SetParams(map[string]any{ | ||||
| 					"indexName": parsed.IndexName, | ||||
| 				}) | ||||
| 				) | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -268,7 +268,7 @@ func (validator *collectionValidator) checkFieldDuplicates(value any) error { | ||||
| 				strconv.Itoa(i): validation.Errors{ | ||||
| 					"name": validation.NewError( | ||||
| 						"validation_duplicated_field_name", | ||||
| 						fmt.Sprintf("Duplicated or invalid field name %q", field.GetName()), | ||||
| 						"Duplicated or invalid field name {{.fieldName}}", | ||||
| 					).SetParams(map[string]any{ | ||||
| 						"fieldName": field.GetName(), | ||||
| 					}), | ||||
| @@ -452,12 +452,12 @@ func (cv *collectionValidator) checkFieldsForUniqueIndex(value any) error { | ||||
| 	for _, name := range names { | ||||
| 		field := cv.new.Fields.GetByName(name) | ||||
| 		if field == nil { | ||||
| 			return validation.NewError("validation_missing_field", fmt.Sprintf("Invalid or missing field %q", name)). | ||||
| 			return validation.NewError("validation_missing_field", "Invalid or missing field {{.fieldName}}"). | ||||
| 				SetParams(map[string]any{"fieldName": name}) | ||||
| 		} | ||||
|  | ||||
| 		if !dbutils.HasSingleColumnUniqueIndex(name, cv.new.Indexes) { | ||||
| 			return validation.NewError("validation_missing_unique_constraint", fmt.Sprintf("The field %q doesn't have a UNIQUE constraint.", name)). | ||||
| 			return validation.NewError("validation_missing_unique_constraint", "The field {{.fieldName}} doesn't have a UNIQUE constraint."). | ||||
| 				SetParams(map[string]any{"fieldName": name}) | ||||
| 		} | ||||
| 	} | ||||
| @@ -566,7 +566,7 @@ func (cv *collectionValidator) checkIndexes(value any) error { | ||||
| 			return validation.Errors{ | ||||
| 				strconv.Itoa(i): validation.NewError( | ||||
| 					"validation_existing_index_name", | ||||
| 					"The index name is already used in "+usedTblName+" collection.", | ||||
| 					"The index name is already used in {{.usedTableName}} collection.", | ||||
| 				).SetParams(map[string]any{"usedTableName": usedTblName}), | ||||
| 			} | ||||
| 		} | ||||
| @@ -649,7 +649,7 @@ func (cv *collectionValidator) checkIndexes(value any) error { | ||||
| 					if !hasMatch { | ||||
| 						return validation.NewError( | ||||
| 							"validation_invalid_unique_system_field_index", | ||||
| 							fmt.Sprintf("Unique index definition on system fields (%q) is invalid or missing.", f.GetName()), | ||||
| 							"Unique index definition on system fields ({{.fieldName}}) is invalid or missing.", | ||||
| 						).SetParams(map[string]any{"fieldName": f.GetName()}) | ||||
| 					} | ||||
|  | ||||
| @@ -669,7 +669,7 @@ func (cv *collectionValidator) checkIndexes(value any) error { | ||||
| 			if !dbutils.HasSingleColumnUniqueIndex(name, indexes) { | ||||
| 				return validation.NewError( | ||||
| 					"validation_missing_required_unique_index", | ||||
| 					`Missing required unique index for field "`+name+`".`, | ||||
| 					`Missing required unique index for field "{{.fieldName}}".`, | ||||
| 				).SetParams(map[string]any{"fieldName": name}) | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -464,7 +464,7 @@ func validateCollectionId(app App, optTypes ...string) validation.RuleFunc { | ||||
| 			return validation.NewError( | ||||
| 				"validation_invalid_collection_type", | ||||
| 				fmt.Sprintf("Invalid collection type - must be %s.", strings.Join(optTypes, ", ")), | ||||
| 			).SetParams(map[string]any{"types": optTypes}) | ||||
| 			) | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package core | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
|  | ||||
| 	validation "github.com/go-ozzo/ozzo-validation/v4" | ||||
| 	"github.com/pocketbase/pocketbase/core/validators" | ||||
| @@ -137,7 +136,7 @@ func (f *EditorField) ValidateValue(ctx context.Context, app App, record *Record | ||||
| 	if int64(len(val)) > maxSize { | ||||
| 		return validation.NewError( | ||||
| 			"validation_content_size_limit", | ||||
| 			fmt.Sprintf("The maximum allowed content size is %v bytes", maxSize), | ||||
| 			"The maximum allowed content size is {{.maxSize}} bytes", | ||||
| 		).SetParams(map[string]any{"maxSize": maxSize}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -250,13 +250,22 @@ func (f *FileField) ValidateValue(ctx context.Context, app App, record *Record) | ||||
| 	addedStrings := f.excludeFiles(existingStrings, oldExistingStrings) | ||||
|  | ||||
| 	if len(addedStrings) > 0 { | ||||
| 		return validation.NewError("validation_invalid_file", "Invalid files:"+strings.Join(cast.ToStringSlice(addedStrings), ", ")). | ||||
| 			SetParams(map[string]any{"invalidFiles": addedStrings}) | ||||
| 		invalidFiles := make([]string, len(addedStrings)) | ||||
| 		for i, invalid := range addedStrings { | ||||
| 			invalidStr := cast.ToString(invalid) | ||||
| 			if len(invalidStr) > 250 { | ||||
| 				invalidStr = invalidStr[:250] | ||||
| 			} | ||||
| 			invalidFiles[i] = invalidStr | ||||
| 		} | ||||
|  | ||||
| 		return validation.NewError("validation_invalid_file", "Invalid new files: {{.invalidFiles}}."). | ||||
| 			SetParams(map[string]any{"invalidFiles": invalidFiles}) | ||||
| 	} | ||||
|  | ||||
| 	maxSelect := f.maxSelect() | ||||
| 	if len(files) > maxSelect { | ||||
| 		return validation.NewError("validation_too_many_files", fmt.Sprintf("The maximum allowed files is %d", maxSelect)). | ||||
| 		return validation.NewError("validation_too_many_files", "The maximum allowed files is {{.maxSelect}}"). | ||||
| 			SetParams(map[string]any{"maxSelect": maxSelect}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package core | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"slices" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| @@ -160,7 +159,7 @@ func (f *JSONField) ValidateValue(ctx context.Context, app App, record *Record) | ||||
| 	if int64(len(raw)) > maxSize { | ||||
| 		return validation.NewError( | ||||
| 			"validation_json_size_limit", | ||||
| 			fmt.Sprintf("The maximum allowed JSON size is %v bytes", maxSize), | ||||
| 			"The maximum allowed JSON size is {{.maxSize}} bytes", | ||||
| 		).SetParams(map[string]any{"maxSize": maxSize}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package core | ||||
| import ( | ||||
| 	"context" | ||||
| 	"database/sql/driver" | ||||
| 	"fmt" | ||||
|  | ||||
| 	validation "github.com/go-ozzo/ozzo-validation/v4" | ||||
| 	"github.com/pocketbase/dbx" | ||||
| @@ -202,13 +201,13 @@ func (f *RelationField) ValidateValue(ctx context.Context, app App, record *Reco | ||||
| 	} | ||||
|  | ||||
| 	if f.MinSelect > 0 && len(ids) < f.MinSelect { | ||||
| 		return validation.NewError("validation_not_enough_values", fmt.Sprintf("Select at least %d", f.MinSelect)). | ||||
| 		return validation.NewError("validation_not_enough_values", "Select at least {{.minSelect}}"). | ||||
| 			SetParams(map[string]any{"minSelect": f.MinSelect}) | ||||
| 	} | ||||
|  | ||||
| 	maxSelect := max(f.MaxSelect, 1) | ||||
| 	if len(ids) > maxSelect { | ||||
| 		return validation.NewError("validation_too_many_values", fmt.Sprintf("Select no more than %d", maxSelect)). | ||||
| 		return validation.NewError("validation_too_many_values", "Select no more than {{.maxSelect}}"). | ||||
| 			SetParams(map[string]any{"maxSelect": maxSelect}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package core | ||||
| import ( | ||||
| 	"context" | ||||
| 	"database/sql/driver" | ||||
| 	"fmt" | ||||
| 	"slices" | ||||
|  | ||||
| 	validation "github.com/go-ozzo/ozzo-validation/v4" | ||||
| @@ -192,14 +191,14 @@ func (f *SelectField) ValidateValue(ctx context.Context, app App, record *Record | ||||
|  | ||||
| 	// check max selected items | ||||
| 	if len(normalizedVal) > maxSelect { | ||||
| 		return validation.NewError("validation_too_many_values", fmt.Sprintf("Select no more than %d", maxSelect)). | ||||
| 		return validation.NewError("validation_too_many_values", "Select no more than {{.maxSelect}}"). | ||||
| 			SetParams(map[string]any{"maxSelect": maxSelect}) | ||||
| 	} | ||||
|  | ||||
| 	// check against the allowed values | ||||
| 	for _, val := range normalizedVal { | ||||
| 		if !slices.Contains(f.Values, val) { | ||||
| 			return validation.NewError("validation_invalid_value", "Invalid value "+val). | ||||
| 			return validation.NewError("validation_invalid_value", "Invalid value {{.value}}"). | ||||
| 				SetParams(map[string]any{"value": val}) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -222,7 +222,7 @@ func (f *TextField) ValidatePlainValue(value string) error { | ||||
| 	length := len([]rune(value)) | ||||
|  | ||||
| 	if f.Min > 0 && length < f.Min { | ||||
| 		return validation.NewError("validation_min_text_constraint", fmt.Sprintf("Must be at least %d character(s)", f.Min)). | ||||
| 		return validation.NewError("validation_min_text_constraint", "Must be at least {{.min}} character(s)"). | ||||
| 			SetParams(map[string]any{"min": f.Min}) | ||||
| 	} | ||||
|  | ||||
| @@ -232,7 +232,7 @@ func (f *TextField) ValidatePlainValue(value string) error { | ||||
| 	} | ||||
|  | ||||
| 	if max > 0 && length > max { | ||||
| 		return validation.NewError("validation_max_text_constraint", fmt.Sprintf("Must be less than %d character(s)", max)). | ||||
| 		return validation.NewError("validation_max_text_constraint", "Must be less than {{.max}} character(s)"). | ||||
| 			SetParams(map[string]any{"max": f.Max}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -639,7 +639,7 @@ func checkUniqueRuleLabel(value any) error { | ||||
| 		if conflicts { | ||||
| 			return validation.Errors{ | ||||
| 				strconv.Itoa(i): validation.Errors{ | ||||
| 					"label": validation.NewError("validation_conflicting_rate_limit_rule", "Rate limit rule configuration with label "+rule.Label+" already exists or conflicts with another rule."). | ||||
| 					"label": validation.NewError("validation_conflicting_rate_limit_rule", "Rate limit rule configuration with label {{.label}} already exists or conflicts with another rule."). | ||||
| 						SetParams(map[string]any{"label": rule.Label}), | ||||
| 				}, | ||||
| 			} | ||||
|   | ||||
| @@ -29,7 +29,7 @@ func UploadedFileSize(maxBytes int64) validation.RuleFunc { | ||||
| 		if v.Size > maxBytes { | ||||
| 			return validation.NewError( | ||||
| 				"validation_file_size_limit", | ||||
| 				fmt.Sprintf("Failed to upload %q - the maximum allowed file size is %v bytes.", v.OriginalName, maxBytes), | ||||
| 				"Failed to upload {{.file}} - the maximum allowed file size is {{.maxSize}} bytes.", | ||||
| 			).SetParams(map[string]any{ | ||||
| 				"file":    v.OriginalName, | ||||
| 				"maxSize": maxBytes, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user