Reapply "🔥 Feature: Enhance CheckConstraint method for improved error handling"

This reverts commit 9e6c8e68df.
pull/3356/head
JIeJaitt 2025-03-18 16:47:06 +08:00
parent c14d0ab87c
commit d10b727fc3
1 changed files with 80 additions and 34 deletions

114
path.go
View File

@ -672,12 +672,18 @@ func getParamConstraintType(constraintPart string) TypeConstraint {
} }
} }
//nolint:errcheck // TODO: Properly check _all_ errors in here, log them & immediately return // CheckConstraint validates if a param matches the given constraint
// Returns true if the param passes the constraint check, false otherwise
func (c *Constraint) CheckConstraint(param string) bool { func (c *Constraint) CheckConstraint(param string) bool {
var err error // First check if there's a custom constraint with the same name
var num int // This allows custom constraints to override built-in constraints
for _, cc := range c.customConstraints {
if cc.Name() == c.Name {
return cc.Execute(param, c.Data...)
}
}
// check data exists // Validate constraint has required data
needOneData := []TypeConstraint{minLenConstraint, maxLenConstraint, lenConstraint, minConstraint, maxConstraint, datetimeConstraint, regexConstraint} needOneData := []TypeConstraint{minLenConstraint, maxLenConstraint, lenConstraint, minConstraint, maxConstraint, datetimeConstraint, regexConstraint}
needTwoData := []TypeConstraint{betweenLenConstraint, rangeConstraint} needTwoData := []TypeConstraint{betweenLenConstraint, rangeConstraint}
@ -693,20 +699,23 @@ func (c *Constraint) CheckConstraint(param string) bool {
} }
} }
// check constraints // Check constraints
switch c.ID { switch c.ID {
case noConstraint: case noConstraint:
for _, cc := range c.customConstraints { // If we reach here with noConstraint, it means we didn't find a matching custom constraint above
if cc.Name() == c.Name { return false
return cc.Execute(param, c.Data...)
}
}
case intConstraint: case intConstraint:
_, err = strconv.Atoi(param) if _, err := strconv.Atoi(param); err != nil {
return false
}
case boolConstraint: case boolConstraint:
_, err = strconv.ParseBool(param) if _, err := strconv.ParseBool(param); err != nil {
return false
}
case floatConstraint: case floatConstraint:
_, err = strconv.ParseFloat(param, 32) if _, err := strconv.ParseFloat(param, 32); err != nil {
return false
}
case alphaConstraint: case alphaConstraint:
for _, r := range param { for _, r := range param {
if !unicode.IsLetter(r) { if !unicode.IsLetter(r) {
@ -714,61 +723,98 @@ func (c *Constraint) CheckConstraint(param string) bool {
} }
} }
case guidConstraint: case guidConstraint:
_, err = uuid.Parse(param) if _, err := uuid.Parse(param); err != nil {
return false
}
case minLenConstraint: case minLenConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
if err != nil {
return false
}
if len(param) < data { if len(param) < data {
return false return false
} }
case maxLenConstraint: case maxLenConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
if err != nil {
return false
}
if len(param) > data { if len(param) > data {
return false return false
} }
case lenConstraint: case lenConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
if err != nil {
return false
}
if len(param) != data { if len(param) != data {
return false return false
} }
case betweenLenConstraint: case betweenLenConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
data2, _ := strconv.Atoi(c.Data[1]) if err != nil {
return false
}
data2, err := strconv.Atoi(c.Data[1])
if err != nil {
return false
}
length := len(param) length := len(param)
if length < data || length > data2 { if length < data || length > data2 {
return false return false
} }
case minConstraint: case minConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
num, err = strconv.Atoi(param) if err != nil {
return false
}
num, err := strconv.Atoi(param)
if err != nil {
return false
}
if num < data { if num < data {
return false return false
} }
case maxConstraint: case maxConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
num, err = strconv.Atoi(param) if err != nil {
return false
}
num, err := strconv.Atoi(param)
if err != nil {
return false
}
if num > data { if num > data {
return false return false
} }
case rangeConstraint: case rangeConstraint:
data, _ := strconv.Atoi(c.Data[0]) data, err := strconv.Atoi(c.Data[0])
data2, _ := strconv.Atoi(c.Data[1]) if err != nil {
num, err = strconv.Atoi(param) return false
}
data2, err := strconv.Atoi(c.Data[1])
if err != nil {
return false
}
num, err := strconv.Atoi(param)
if err != nil {
return false
}
if num < data || num > data2 { if num < data || num > data2 {
return false return false
} }
case datetimeConstraint: case datetimeConstraint:
_, err = time.Parse(c.Data[0], param) if _, err := time.Parse(c.Data[0], param); err != nil {
return false
}
case regexConstraint: case regexConstraint:
if c.RegexCompiler == nil {
return false
}
if match := c.RegexCompiler.MatchString(param); !match { if match := c.RegexCompiler.MatchString(param); !match {
return false return false
} }
} }
return err == nil return true
} }