5

printf-style function with dynamic format string and no further arguments should use print-style function instead

My VScode keeps highlighting my fmt.Fprintf(w, prettyJSON.String()) statements with the warning stated above. Not sure what it means, or how to fix. Here is an example on how I use Fprintf():

func (s *Server) getWorkSpaces(w http.ResponseWriter, r *http.Request) {
    client := &http.Client{}
    var prettyJSON bytes.Buffer
    req, err := http.NewRequest("GET", "url.com", nil)
    if err != nil {
        // if there was an error parsing the request, return an error to user and quit function
        responses.ERROR(w, http.StatusBadRequest, fmt.Errorf("unable to read request body: %v", err))
        return
    }


    resp, err := client.Do(req)
    if err != nil {
        // if there was an error parsing the request, return an error to user and quit function
        responses.ERROR(w, http.StatusBadRequest, fmt.Errorf("unable to read request body: %v", err))
        return
    }

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln(err)
    }
    error := json.Indent(&prettyJSON, body, "", "\t")
    if error != nil {
        log.Println("JSON parse error: ", error)
        return
    }

    fmt.Fprintf(w, prettyJSON.String())
}

How can I stop this error? Could someone explain to me why my VScode is throwing that up on the screen? Note that my code runs and works well.

andres
  • 1,558
  • 7
  • 24
  • 62

1 Answers1

9

fmt.Fprintf() expects a format string that may contain verbs that will be substituted with arguments. If you do not pass arguments, that hints you're likely not having / using a format string, so you shouldn't use fmt.Fprintf() in the first place.

To just write arguments into an io.Writer, use fmt.Fprint().

fmt.Fprint(w, prettyJSON.String())

The warning is more than justified from vet, because the format string may not get outputted as-is:

fmt.Print("%%\n")
fmt.Printf("%%\n")

The above prints (try it on the Go Playground):

%%
%

The % is a special character in format strings, and to emit (output) a single % sign you have to use double % in the format string. This is just to prove the point, there are other differences.

See related questions:

No placeholders in format string

Format a Go string without printing?

icza
  • 389,944
  • 63
  • 907
  • 827
  • thank you for your response. Now I understand! – andres Feb 09 '22 at 15:34
  • This is a question that is better answered for a case-by-case basis, but when given the chance, which one is better to use? `Fprintf` with arguments, or a simple `Fprint`? – andres Feb 09 '22 at 15:34
  • 1
    `Fprintf()` can be used to generate formatted output easily. `Fprint` is to just write arguments. E.g. `Fprintf(w, "Bob is %d years old", 12)` will output `Bob is 12 years old`. – icza Feb 09 '22 at 15:36
  • 1
    See [Format a Go string without printing?](https://stackoverflow.com/questions/11123865/format-a-go-string-without-printing/31742265#31742265) for details. – icza Feb 09 '22 at 15:38