Flag error strings that end with a newline Signed-off-by: Joe Tsai <joetsai@google.com>
diff --git a/lint.go b/lint.go index 59fea7c..2a2e607 100644 --- a/lint.go +++ b/lint.go
@@ -1155,21 +1155,30 @@ } } -func lintCapAndPunct(s string) (isCap, isPunct bool) { +func lintErrorString(s string) (isClean bool, conf float64) { + const basicConfidence = 0.8 + const capConfidence = basicConfidence - 0.2 first, firstN := utf8.DecodeRuneInString(s) last, _ := utf8.DecodeLastRuneInString(s) - isPunct = last == '.' || last == ':' || last == '!' - isCap = unicode.IsUpper(first) - if isCap && len(s) > firstN { - // Don't flag strings starting with something that looks like an initialism. - if second, _ := utf8.DecodeRuneInString(s[firstN:]); unicode.IsUpper(second) { - isCap = false + if last == '.' || last == ':' || last == '!' || last == '\n' { + return false, basicConfidence + } + if unicode.IsUpper(first) { + // People use proper nouns and exported Go identifiers in error strings, + // so decrease the confidence of warnings for capitalization. + if len(s) <= firstN { + return false, capConfidence + } + // Flag strings starting with something that doesn't look like an initialism. + if second, _ := utf8.DecodeRuneInString(s[firstN:]); !unicode.IsUpper(second) { + return false, capConfidence } } - return + return true, 0 } -// lintErrorStrings examines error strings. It complains if they are capitalized or end in punctuation. +// lintErrorStrings examines error strings. +// It complains if they are capitalized or end in punctuation or a newline. func (f *file) lintErrorStrings() { f.walk(func(node ast.Node) bool { ce, ok := node.(*ast.CallExpr) @@ -1190,25 +1199,13 @@ if s == "" { return true } - isCap, isPunct := lintCapAndPunct(s) - var msg string - switch { - case isCap && isPunct: - msg = "error strings should not be capitalized and should not end with punctuation" - case isCap: - msg = "error strings should not be capitalized" - case isPunct: - msg = "error strings should not end with punctuation" - default: + clean, conf := lintErrorString(s) + if clean { return true } - // People use proper nouns and exported Go identifiers in error strings, - // so decrease the confidence of warnings for capitalization. - conf := 0.8 - if isCap { - conf = 0.6 - } - f.errorf(str, conf, link(styleGuideBase+"#error-strings"), category("errors"), msg) + + f.errorf(str, conf, link(styleGuideBase+"#error-strings"), category("errors"), + "error strings should not be capitalized or end with punctuation or a newline") return true }) }
diff --git a/testdata/errors.go b/testdata/errors.go index 396dcfc..3435bf8 100644 --- a/testdata/errors.go +++ b/testdata/errors.go
@@ -27,10 +27,11 @@ // Check for the error strings themselves. func g(x int) error { - if x < 1 { - return fmt.Errorf("This %d is too low", x) // MATCH /error strings.*not be capitalized/ - } else if x == 0 { - return fmt.Errorf("XML time") // ok - } - return errors.New(`too much stuff.`) // MATCH /error strings.*not end with punctuation/ + var err error + err = fmt.Errorf("This %d is too low", x) // MATCH /error strings.*be capitalized/ + err = fmt.Errorf("XML time") // ok + err = fmt.Errorf("newlines are fun\n") // MATCH /error strings.*end with punctuation/ + err = fmt.Errorf("Newlines are really fun\n") // MATCH /error strings.+not be capitalized/ + err = errors.New(`too much stuff.`) // MATCH /error strings.*end with punctuation/ + return err }