updated error messages
This commit is contained in:
parent
5a5211d7f2
commit
fab334fca6
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue