updated error messages

This commit is contained in:
Gani Georgiev 2024-11-25 11:28:20 +02:00
parent 5a5211d7f2
commit fab334fca6
14 changed files with 36 additions and 31 deletions

View File

@ -2,6 +2,8 @@
- Added `RequestEvent.Blob(status, contentType string, bytes)` response write helper ([#5940](https://github.com/pocketbase/pocketbase/discussions/5940)). - 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 ## v0.23.0

View File

@ -175,7 +175,7 @@ type recordOAuth2LoginForm struct {
func (form *recordOAuth2LoginForm) validate() error { func (form *recordOAuth2LoginForm) validate() error {
return validation.ValidateStruct(form, 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.Code, validation.Required),
validation.Field(&form.RedirectURL, 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) _, ok := form.collection.OAuth2.GetProviderConfig(name)
if !ok { 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}) SetParams(map[string]any{"name": name})
} }

View File

@ -445,7 +445,7 @@ func checkForDuplicatedProviders(value any) error {
if _, ok := existing[c.Name]; ok { if _, ok := existing[c.Name]; ok {
return validation.Errors{ return validation.Errors{
strconv.Itoa(i): 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}), SetParams(map[string]any{"name": c.Name}),
}, },
} }
@ -493,7 +493,7 @@ func checkProviderName(value any) error {
} }
if _, err := auth.NewProviderByName(name); err != nil { 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}) SetParams(map[string]any{"name": name})
} }

View File

@ -349,9 +349,7 @@ func createCollectionIndexes(app App, collection *Collection) error {
errs[strconv.Itoa(i)] = validation.NewError( errs[strconv.Itoa(i)] = validation.NewError(
"validation_invalid_index_expression", "validation_invalid_index_expression",
fmt.Sprintf("Failed to create index %s - %v.", parsed.IndexName, err.Error()), fmt.Sprintf("Failed to create index %s - %v.", parsed.IndexName, err.Error()),
).SetParams(map[string]any{ )
"indexName": parsed.IndexName,
})
continue continue
} }
} }

View File

@ -268,7 +268,7 @@ func (validator *collectionValidator) checkFieldDuplicates(value any) error {
strconv.Itoa(i): validation.Errors{ strconv.Itoa(i): validation.Errors{
"name": validation.NewError( "name": validation.NewError(
"validation_duplicated_field_name", "validation_duplicated_field_name",
fmt.Sprintf("Duplicated or invalid field name %q", field.GetName()), "Duplicated or invalid field name {{.fieldName}}",
).SetParams(map[string]any{ ).SetParams(map[string]any{
"fieldName": field.GetName(), "fieldName": field.GetName(),
}), }),
@ -452,12 +452,12 @@ func (cv *collectionValidator) checkFieldsForUniqueIndex(value any) error {
for _, name := range names { for _, name := range names {
field := cv.new.Fields.GetByName(name) field := cv.new.Fields.GetByName(name)
if field == nil { 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}) SetParams(map[string]any{"fieldName": name})
} }
if !dbutils.HasSingleColumnUniqueIndex(name, cv.new.Indexes) { 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}) SetParams(map[string]any{"fieldName": name})
} }
} }
@ -566,7 +566,7 @@ func (cv *collectionValidator) checkIndexes(value any) error {
return validation.Errors{ return validation.Errors{
strconv.Itoa(i): validation.NewError( strconv.Itoa(i): validation.NewError(
"validation_existing_index_name", "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}), ).SetParams(map[string]any{"usedTableName": usedTblName}),
} }
} }
@ -649,7 +649,7 @@ func (cv *collectionValidator) checkIndexes(value any) error {
if !hasMatch { if !hasMatch {
return validation.NewError( return validation.NewError(
"validation_invalid_unique_system_field_index", "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()}) ).SetParams(map[string]any{"fieldName": f.GetName()})
} }
@ -669,7 +669,7 @@ func (cv *collectionValidator) checkIndexes(value any) error {
if !dbutils.HasSingleColumnUniqueIndex(name, indexes) { if !dbutils.HasSingleColumnUniqueIndex(name, indexes) {
return validation.NewError( return validation.NewError(
"validation_missing_required_unique_index", "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}) ).SetParams(map[string]any{"fieldName": name})
} }
} }

View File

@ -464,7 +464,7 @@ func validateCollectionId(app App, optTypes ...string) validation.RuleFunc {
return validation.NewError( return validation.NewError(
"validation_invalid_collection_type", "validation_invalid_collection_type",
fmt.Sprintf("Invalid collection type - must be %s.", strings.Join(optTypes, ", ")), fmt.Sprintf("Invalid collection type - must be %s.", strings.Join(optTypes, ", ")),
).SetParams(map[string]any{"types": optTypes}) )
} }
return nil return nil

View File

@ -2,7 +2,6 @@ package core
import ( import (
"context" "context"
"fmt"
validation "github.com/go-ozzo/ozzo-validation/v4" validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/pocketbase/pocketbase/core/validators" "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 { if int64(len(val)) > maxSize {
return validation.NewError( return validation.NewError(
"validation_content_size_limit", "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}) ).SetParams(map[string]any{"maxSize": maxSize})
} }

View File

@ -250,13 +250,22 @@ func (f *FileField) ValidateValue(ctx context.Context, app App, record *Record)
addedStrings := f.excludeFiles(existingStrings, oldExistingStrings) addedStrings := f.excludeFiles(existingStrings, oldExistingStrings)
if len(addedStrings) > 0 { if len(addedStrings) > 0 {
return validation.NewError("validation_invalid_file", "Invalid files:"+strings.Join(cast.ToStringSlice(addedStrings), ", ")). invalidFiles := make([]string, len(addedStrings))
SetParams(map[string]any{"invalidFiles": 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() maxSelect := f.maxSelect()
if len(files) > 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}) SetParams(map[string]any{"maxSelect": maxSelect})
} }

View File

@ -2,7 +2,6 @@ package core
import ( import (
"context" "context"
"fmt"
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
@ -160,7 +159,7 @@ func (f *JSONField) ValidateValue(ctx context.Context, app App, record *Record)
if int64(len(raw)) > maxSize { if int64(len(raw)) > maxSize {
return validation.NewError( return validation.NewError(
"validation_json_size_limit", "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}) ).SetParams(map[string]any{"maxSize": maxSize})
} }

View File

@ -3,7 +3,6 @@ package core
import ( import (
"context" "context"
"database/sql/driver" "database/sql/driver"
"fmt"
validation "github.com/go-ozzo/ozzo-validation/v4" validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/pocketbase/dbx" "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 { 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}) SetParams(map[string]any{"minSelect": f.MinSelect})
} }
maxSelect := max(f.MaxSelect, 1) maxSelect := max(f.MaxSelect, 1)
if len(ids) > maxSelect { 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}) SetParams(map[string]any{"maxSelect": maxSelect})
} }

View File

@ -3,7 +3,6 @@ package core
import ( import (
"context" "context"
"database/sql/driver" "database/sql/driver"
"fmt"
"slices" "slices"
validation "github.com/go-ozzo/ozzo-validation/v4" 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 // check max selected items
if len(normalizedVal) > maxSelect { 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}) SetParams(map[string]any{"maxSelect": maxSelect})
} }
// check against the allowed values // check against the allowed values
for _, val := range normalizedVal { for _, val := range normalizedVal {
if !slices.Contains(f.Values, val) { 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}) SetParams(map[string]any{"value": val})
} }
} }

View File

@ -222,7 +222,7 @@ func (f *TextField) ValidatePlainValue(value string) error {
length := len([]rune(value)) length := len([]rune(value))
if f.Min > 0 && length < f.Min { 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}) SetParams(map[string]any{"min": f.Min})
} }
@ -232,7 +232,7 @@ func (f *TextField) ValidatePlainValue(value string) error {
} }
if max > 0 && length > max { 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}) SetParams(map[string]any{"max": f.Max})
} }

View File

@ -639,7 +639,7 @@ func checkUniqueRuleLabel(value any) error {
if conflicts { if conflicts {
return validation.Errors{ return validation.Errors{
strconv.Itoa(i): 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}), SetParams(map[string]any{"label": rule.Label}),
}, },
} }

View File

@ -29,7 +29,7 @@ func UploadedFileSize(maxBytes int64) validation.RuleFunc {
if v.Size > maxBytes { if v.Size > maxBytes {
return validation.NewError( return validation.NewError(
"validation_file_size_limit", "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{ ).SetParams(map[string]any{
"file": v.OriginalName, "file": v.OriginalName,
"maxSize": maxBytes, "maxSize": maxBytes,