16

I have a problem with error text.

If I use the error message shown below, the editor's linter gives a warning like this: "error strings should not end with punctuation or a newline":

return errors.New("Test!")
                       ^

The question is: why shouldn't I use punctuation? What is the real reason behind it?

blackgreen
  • 34,072
  • 23
  • 111
  • 129
muhammed ikinci
  • 667
  • 2
  • 6
  • 18
  • 2
    That's the linter warning you I guess, not the go compiler - https://staticcheck.io/docs/checks#ST1005 – Inian Aug 15 '21 at 15:00
  • 4
    @muhammedikinci did you check the link? "Error strings should not be capitalized (unless beginning with > proper nouns or acronyms) or end with punctuation, since they are > usually printed following other context. That is, use > fmt.Errorf("something bad") not fmt.Errorf("Something bad"), so > that log.Printf("Reading %s: %v", filename, err) formats without a > spurious capital letter mid-message. " – eis Aug 15 '21 at 15:11
  • @eis I checked https://github.com/golang/go/wiki/CodeReviewComments#error-strings and thank you so much. I understand the reason now. – muhammed ikinci Aug 15 '21 at 15:15

1 Answers1

21

Errors may be wrapped up the call stack and their messages may be concatenated before printing. If you add punctuation, the end result might be weird from a grammatical standpoint.

As the link in the comment says:

Error strings should not be capitalized (unless beginning with proper nouns or acronyms) or end with punctuation, since they are usually printed following other context.

As an example, consider the following program:

func main() {
    fmt.Println(foo()) // bar failed: baz failed!: some problem
}

func foo() error {
    err := bar()
    if err != nil {
        return fmt.Errorf("%s: %w", "bar failed", err)
    }
    return nil
}

func bar() error {
    err := baz()
    if err != nil {
        return fmt.Errorf("%s: %w", "baz failed!", err)
    }
    return nil
}

func baz() error {
    return errors.New("some problem")
}

Of course this example is contrived, but the point is that in a real-world scenario you don't know how your libraries — or users of your code — will format their errors. The issue is probably easier to demonstrate with the error package "github.com/pkg/errors", where each call to Wrap results in a colon (:) separator when printing the message:

package main

import (
    "github.com/pkg/errors"
    "fmt"
)

func main() {
    fmt.Println(errors.Wrap(errors.Wrap(errors.Wrap(errors.New("foo"), "bar"), "baz"), "quux"))
    // quux: baz: bar: foo 
}

Playground: https://play.golang.org/p/dxI2301IX1P

blackgreen
  • 34,072
  • 23
  • 111
  • 129