检查对fmt.Errorf()的调用是否失败[关闭]

In Go, the function fmt.Errorf() returns an error interface.
What's the proper way to check if fmt.Errorf() itself failed?

Errorf formats according to a format specifier and returns the string as a value that satisfies error. The fmt package's Errorf function lets us use the package's formatting features to create descriptive error messages.

func Errorf(format string, a ...interface{}) error {
    return errors.New(Sprintf(format, a...))
}

And New returns an error that formats as the given text.

func New(text string) error {
    return &errorString{text}
}

And errorString is a trivial implementation of error.

type errorString struct {
    s string
}

So Basically what it is returning is field of string type.

fmt.Errorf returns basically a string that is wrapped as an error. If you provide wrong arguments like in the following example, you still get an error but with the error message of the format fault inside the string message:

package main

import "fmt"

func main() {
    fmt.Println(fmt.Errorf("abc", 5))
}

outputs the error string:

abc%!(EXTRA int=5)

These functions are not expected to be used in a context where you do not know the arguments that you are providing. The typical use case is that you "test" your formatting code when you write it. In your output code you will spot these error messages easily. You should just make sure to test these calls before going into production.

The danger of a panic in these functions is negligible, panics are caught as stated in the documentation:

If an Error or String method triggers a panic when called by a print routine, the fmt
package reformats the error message from the panic, decorating it with an indication
that it came through the fmt package. For example, if a String method calls
panic("bad"), the resulting formatted message will look like

%!s(PANIC=bad)

You should try to catch errors at compile and test time, not run time. For fmt.Errorf, run go vet.

For example,

package main

import "fmt"

func main() {
    err := fmt.Errorf("%v")
    fmt.Println(err)
}

Output:

$ go vet errorf.go
# command-line-arguments
./errorf.go:6: Errorf format %v reads arg #1, but call has 0 args
$ 

$ go run errorf.go
%!v(MISSING)
$ 

Command vet

Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string. Vet uses heuristics that do not guarantee all reports are genuine problems, but it can find errors not caught by the compilers.

Vet is normally invoked using the go command by running "go vet":

go vet

Printf family

Flag: -printf

Suspicious calls to functions in the Printf family, including any functions with these names, disregarding case:

Print Printf Println
Fprint Fprintf Fprintln
Sprint Sprintf Sprintln
Error Errorf
Fatal Fatalf
Log Logf
Panic Panicf Panicln

The -printfuncs flag can be used to redefine this list. If the function name ends with an 'f', the function is assumed to take a format descriptor string in the manner of fmt.Printf. If not, vet complains about arguments that look like format descriptor strings.

It also checks for errors such as using a Writer as the first argument of Printf.


Formatted output errors, by design, are a special case. For example, an error when reporting an error can be circular.

Package fmt

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.

If an Error or String method triggers a panic when called by a print routine, the fmt package reformats the error message from the panic, decorating it with an indication that it came through the fmt package. For example, if a String method calls panic("bad"), the resulting formatted message will look like

%!s(PANIC=bad)

The %!s just shows the print verb in use when the failure occurred. If the panic is caused by a nil receiver to an Error or String method, however, the output is the undecorated string, "".