mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-09 17:37:20 -06:00
fix(web): handle TypeCastError when building form validation messages (#40212)
Fixes https://github.com/go-gitea/gitea/issues/40210 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -28,10 +28,13 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// TODO: need to refactor the binding package, let the rules provide error message directly.
|
||||
// Don't use the fragile Classification and useless&incorrect Message field in the future.
|
||||
|
||||
errContentType = "ContentTypeError"
|
||||
errDeserialization = "DeserializationError"
|
||||
errTypeCast = "TypeCastError"
|
||||
errRule = "RuleError"
|
||||
ErrTypeCast = errTypeCast
|
||||
|
||||
ErrRequired = "RequiredError"
|
||||
ErrAlphaDashDot = "AlphaDashDotError"
|
||||
|
||||
@@ -174,6 +174,8 @@ func BuildValidationErrorForUser(f any, l translation.Locale, bindingErrs valida
|
||||
errorMessage = l.TrString("form.invalid_group_team_map_error", fieldDisplayName, bindingErrMsg)
|
||||
case validation.ErrInvalidBadgeSlug:
|
||||
errorMessage = l.TrString("form.invalid_slug_error", fieldDisplayName)
|
||||
case binding.ErrTypeCast:
|
||||
errorMessage = l.TrString("form.field_invalid_message", fieldDisplayName, bindingErrMsg)
|
||||
default:
|
||||
setting.PanicInDevOrTesting("unknown binding error classification for field %T.%s: %v, err: %s", f, errorFieldName, classification, bindingErrMsg)
|
||||
var msg string
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/translation"
|
||||
@@ -12,17 +15,28 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type testRangeForm struct {
|
||||
type testBindingForm struct {
|
||||
FormDefaultValidator
|
||||
Hours int `binding:"Range(0,1000)"`
|
||||
}
|
||||
|
||||
func TestBuildValidationErrorForUser(t *testing.T) {
|
||||
// an out-of-range value must reach its own message instead of the panicking "default" branch
|
||||
form := &testRangeForm{Hours: 2000}
|
||||
errs := validation.Binder().Validate(t.Context(), form)
|
||||
errorMessage, errorFieldName, fieldNames := BuildValidationErrorForUser(form, translation.MockLocale{}, errs)
|
||||
assert.Equal(t, "form.range_error:form.Hours,0,1000", errorMessage)
|
||||
assert.Equal(t, "Hours", errorFieldName)
|
||||
assert.Equal(t, []string{"Hours"}, fieldNames)
|
||||
t.Run("Range", func(t *testing.T) {
|
||||
form := &testBindingForm{Hours: 2000}
|
||||
errs := validation.Binder().Validate(t.Context(), form)
|
||||
errorMessage, errorFieldName, fieldNames := BuildValidationErrorForUser(form, translation.MockLocale{}, errs)
|
||||
assert.Equal(t, "form.range_error:form.Hours,0,1000", errorMessage)
|
||||
assert.Equal(t, "Hours", errorFieldName)
|
||||
assert.Equal(t, []string{"Hours"}, fieldNames)
|
||||
})
|
||||
t.Run("TypeCast", func(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("hours=abc"))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
form := &testBindingForm{}
|
||||
errs := validation.Binder().Bind(req, form)
|
||||
errorMessage, errorFieldName, fieldNames := BuildValidationErrorForUser(form, translation.MockLocale{}, errs)
|
||||
assert.Equal(t, "form.field_invalid_message:form.Hours,Value could not be parsed as integer", errorMessage)
|
||||
assert.Equal(t, "Hours", errorFieldName)
|
||||
assert.Equal(t, []string{"Hours"}, fieldNames)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user