Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would a call to fmt.Sprint(e) inside the Error() method result in an infinite loop?

Tags:

go

fmt.Sprint(e) will call e.Error() to convert the value e to a string. If the Error() method calls fmt.Sprint(e), then the program recurses until out of memory.

You can break the recursion by converting the e to a value without a String or Error method.


fmt.Sprint(e) will invoke the following piece of codes from "fmt/print.go"

switch verb {
    case 'v', 's', 'x', 'X', 'q':
        // Is it an error or Stringer?
        // The duplication in the bodies is necessary:
        // setting handled and deferring catchPanic
        // must happen before calling the method.
        switch v := p.arg.(type) {
        case error:
            handled = true
            defer p.catchPanic(p.arg, verb, "Error")
            p.fmtString(v.Error(), verb)
            return

        case Stringer:
            handled = true
            defer p.catchPanic(p.arg, verb, "String")
            p.fmtString(v.String(), verb)
            return
        }
    }

As error case appears first, v.Error() will be executed. Endless loop here!