mirror of
https://github.com/mgechev/revive.git
synced 2025-11-23 22:04:49 +02:00
refactor: replace panic with error in rules (#1126)
Co-authored-by: chavacava <salvadorcavadini+github@gmail.com> Co-authored-by: Oleksandr Redko <oleksandr.red+github@gmail.com>
This commit is contained in:
committed by
GitHub
parent
10d9697cc2
commit
9b15f3fcb6
@@ -23,7 +23,11 @@ func (*StringFormatRule) Apply(file *lint.File, arguments lint.Arguments) []lint
|
||||
}
|
||||
|
||||
w := lintStringFormatRule{onFailure: onFailure}
|
||||
w.parseArguments(arguments)
|
||||
err := w.parseArguments(arguments)
|
||||
if err != nil {
|
||||
return newInternalFailureError(err)
|
||||
}
|
||||
|
||||
ast.Walk(w, file.AST)
|
||||
|
||||
return failures
|
||||
@@ -41,10 +45,9 @@ func (StringFormatRule) ParseArgumentsTest(arguments lint.Arguments) *string {
|
||||
// Parse the arguments in a goroutine, defer a recover() call, return the error encountered (or nil if there was no error)
|
||||
go func() {
|
||||
defer func() {
|
||||
err := recover()
|
||||
err := w.parseArguments(arguments)
|
||||
c <- err
|
||||
}()
|
||||
w.parseArguments(arguments)
|
||||
}()
|
||||
err := <-c
|
||||
if err != nil {
|
||||
@@ -81,9 +84,12 @@ const identRegex = "[_A-Za-z][_A-Za-z0-9]*"
|
||||
var parseStringFormatScope = regexp.MustCompile(
|
||||
fmt.Sprintf("^(%s(?:\\.%s)?)(?:\\[([0-9]+)\\](?:\\.(%s))?)?$", identRegex, identRegex, identRegex))
|
||||
|
||||
func (w *lintStringFormatRule) parseArguments(arguments lint.Arguments) {
|
||||
func (w *lintStringFormatRule) parseArguments(arguments lint.Arguments) error {
|
||||
for i, argument := range arguments {
|
||||
scopes, regex, negated, errorMessage := w.parseArgument(argument, i)
|
||||
scopes, regex, negated, errorMessage, err := w.parseArgument(argument, i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.rules = append(w.rules, stringFormatSubrule{
|
||||
parent: w,
|
||||
scopes: scopes,
|
||||
@@ -92,30 +98,31 @@ func (w *lintStringFormatRule) parseArguments(arguments lint.Arguments) {
|
||||
errorMessage: errorMessage,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes stringFormatSubruleScopes, regex *regexp.Regexp, negated bool, errorMessage string) {
|
||||
func (w lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes stringFormatSubruleScopes, regex *regexp.Regexp, negated bool, errorMessage string, err error) {
|
||||
g, ok := argument.([]any) // Cast to generic slice first
|
||||
if !ok {
|
||||
w.configError("argument is not a slice", ruleNum, 0)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.configError("argument is not a slice", ruleNum, 0)
|
||||
}
|
||||
if len(g) < 2 {
|
||||
w.configError("less than two slices found in argument, scope and regex are required", ruleNum, len(g)-1)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.configError("less than two slices found in argument, scope and regex are required", ruleNum, len(g)-1)
|
||||
}
|
||||
rule := make([]string, len(g))
|
||||
for i, obj := range g {
|
||||
val, ok := obj.(string)
|
||||
if !ok {
|
||||
w.configError("unexpected value, string was expected", ruleNum, i)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.configError("unexpected value, string was expected", ruleNum, i)
|
||||
}
|
||||
rule[i] = val
|
||||
}
|
||||
|
||||
// Validate scope and regex length
|
||||
if rule[0] == "" {
|
||||
w.configError("empty scope provided", ruleNum, 0)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.configError("empty scope provided", ruleNum, 0)
|
||||
} else if len(rule[1]) < 2 {
|
||||
w.configError("regex is too small (regexes should begin and end with '/')", ruleNum, 1)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.configError("regex is too small (regexes should begin and end with '/')", ruleNum, 1)
|
||||
}
|
||||
|
||||
// Parse rule scopes
|
||||
@@ -126,24 +133,24 @@ func (w lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes s
|
||||
rawScope = strings.TrimSpace(rawScope)
|
||||
|
||||
if len(rawScope) == 0 {
|
||||
w.parseScopeError("empty scope in rule scopes:", ruleNum, 0, scopeNum)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError("empty scope in rule scopes:", ruleNum, 0, scopeNum)
|
||||
}
|
||||
|
||||
scope := stringFormatSubruleScope{}
|
||||
matches := parseStringFormatScope.FindStringSubmatch(rawScope)
|
||||
if matches == nil {
|
||||
// The rule's scope didn't match the parsing regex at all, probably a configuration error
|
||||
w.parseScopeError("unable to parse rule scope", ruleNum, 0, scopeNum)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError("unable to parse rule scope", ruleNum, 0, scopeNum)
|
||||
} else if len(matches) != 4 {
|
||||
// The rule's scope matched the parsing regex, but an unexpected number of submatches was returned, probably a bug
|
||||
w.parseScopeError(fmt.Sprintf("unexpected number of submatches when parsing scope: %d, expected 4", len(matches)), ruleNum, 0, scopeNum)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError(fmt.Sprintf("unexpected number of submatches when parsing scope: %d, expected 4", len(matches)), ruleNum, 0, scopeNum)
|
||||
}
|
||||
scope.funcName = matches[1]
|
||||
if len(matches[2]) > 0 {
|
||||
var err error
|
||||
scope.argument, err = strconv.Atoi(matches[2])
|
||||
if err != nil {
|
||||
w.parseScopeError("unable to parse argument number in rule scope", ruleNum, 0, scopeNum)
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.parseScopeError("unable to parse argument number in rule scope", ruleNum, 0, scopeNum)
|
||||
}
|
||||
}
|
||||
if len(matches[3]) > 0 {
|
||||
@@ -159,31 +166,31 @@ func (w lintStringFormatRule) parseArgument(argument any, ruleNum int) (scopes s
|
||||
if negated {
|
||||
offset++
|
||||
}
|
||||
regex, err := regexp.Compile(rule[1][offset : len(rule[1])-1])
|
||||
if err != nil {
|
||||
w.parseError(fmt.Sprintf("unable to compile %s as regexp", rule[1]), ruleNum, 1)
|
||||
regex, errr := regexp.Compile(rule[1][offset : len(rule[1])-1])
|
||||
if errr != nil {
|
||||
return stringFormatSubruleScopes{}, regex, false, "", w.parseError(fmt.Sprintf("unable to compile %s as regexp", rule[1]), ruleNum, 1)
|
||||
}
|
||||
|
||||
// Use custom error message if provided
|
||||
if len(rule) == 3 {
|
||||
errorMessage = rule[2]
|
||||
}
|
||||
return scopes, regex, negated, errorMessage
|
||||
return scopes, regex, negated, errorMessage, nil
|
||||
}
|
||||
|
||||
// Report an invalid config, this is specifically the user's fault
|
||||
func (lintStringFormatRule) configError(msg string, ruleNum, option int) {
|
||||
panic(fmt.Sprintf("invalid configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option))
|
||||
func (lintStringFormatRule) configError(msg string, ruleNum, option int) error {
|
||||
return fmt.Errorf("invalid configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
|
||||
}
|
||||
|
||||
// Report a general config parsing failure, this may be the user's fault, but it isn't known for certain
|
||||
func (lintStringFormatRule) parseError(msg string, ruleNum, option int) {
|
||||
panic(fmt.Sprintf("failed to parse configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option))
|
||||
func (lintStringFormatRule) parseError(msg string, ruleNum, option int) error {
|
||||
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
|
||||
}
|
||||
|
||||
// Report a general scope config parsing failure, this may be the user's fault, but it isn't known for certain
|
||||
func (lintStringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) {
|
||||
panic(fmt.Sprintf("failed to parse configuration for string-format: %s [argument %d, option %d, scope index %d]", msg, ruleNum, option, scopeNum))
|
||||
func (lintStringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) error {
|
||||
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d, scope index %d]", msg, ruleNum, option, scopeNum)
|
||||
}
|
||||
|
||||
func (w lintStringFormatRule) Visit(node ast.Node) ast.Visitor {
|
||||
|
||||
Reference in New Issue
Block a user