4

I've encountered some go code that appears to use %e for formatting an error for display to the screen. A simplified version would be code like this

err := errors.New("La de da")
fmt.Printf("%e\n", err)

outputs

&{%!e(string=La de da)}

However, if I look at the go manual, it says %e is for formatting floating point numbers in scientific notation. That output doesn't look like scientific notation, so I'm wondering

  1. If this is a specific notation, what is it? (i.e. is there a %. formatting option I could use to get that format)

  2. If it's not a specific notation, what weird thing is going on under the hood that leads to an error being rendered in this way?

  3. What silly, obvious thing am I missing that renders most of what I've said in this post wrong?

8
  • 1
    Thank you for feedback @jimB -- I realize the error isn't a floating point number -- but I'd expect a string formater to either 1. Complain about the type mismatch, 2. Try to cast the variable as the other type. There's some third thing happening here that I don't follow. I'd like to understand what format is, and why golang chose it. Commented Mar 22, 2018 at 22:06
  • 1
    golang.org/pkg/fmt/#hdr-Scanning scroll up a bit to " Format errors: " The most relevant to your example being Wrong type or unknown verb: %!verb(type=value). Commented Mar 22, 2018 at 22:10
  • 1
    The fmt package uses the %! output to indicate a format errors. Commented Mar 22, 2018 at 22:10
  • 2
    As far as I'm concerned you're free to close/delete the question @AlanStorm. I'm glad I could be of help though. Commented Mar 22, 2018 at 22:20
  • 1
    Error types can implement fmt.Formatter such that the %e format actually produces useful output. That would be unusual though. Commented Mar 22, 2018 at 23:11

2 Answers 2

7

Read the Go documentation.

Package fmt

Printing

Format errors:

If an invalid argument is given for a verb, such as providing a string to %d, the generated string will contain a description of the problem, as in these examples:

Wrong type or unknown verb: %!verb(type=value)
  Printf("%d", hi):          %!d(string=hi)
Too many arguments: %!(EXTRA type=value)
  Printf("hi", "guys"):      hi%!(EXTRA string=guys)
Too few arguments: %!verb(MISSING)
  Printf("hi%d"):            hi%!d(MISSING)
Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
  Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
  Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
Invalid or invalid use of argument index: %!(BADINDEX)
  Printf("%*[2]d", 7):       %!d(BADINDEX)
  Printf("%.[2]d", 7):       %!d(BADINDEX)

All errors begin with the string "%!" followed sometimes by a single character (the verb) and end with a parenthesized description.


For your example,

package main

import (
    "errors"
    "fmt"
)

func main() {
    err := errors.New("La de da")
    fmt.Printf("%e\n", err)
}

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

Output:

&{%!e(string=La de da)}

Documentation:

All errors begin with the string "%!" followed sometimes by a single character (the verb) and end with a parenthesized description.

Wrong type or unknown verb: %!verb(type=value)
  Printf("%d", hi):          %!d(string=hi)
Sign up to request clarification or add additional context in comments.

Comments

-1

When formatting errors into strings using fmt.Printf()/Println(), you can do the following:

err := fnThatReturnsErr()
if err != nil {
  fmt.Println("The error is %v", err)
}

I believe %v is the formatting option you were looking for.

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
This is not correct. %w only works in the special case of fmt.Errorf("more details %w", err). And what it produces isn't (only) a string with the error's message in it, but a "wrapped error", that is an error which extends an already existing error. This allows adding more information while still using errors.Is(...) to check for underlying errors

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.