3

How to get error as string from an error interface?

I want to assign ERROR: Fake error! to a variable and then convert it to a slice []byte(error_str)

prefix_err := "ERROR: "

defer func() {
    if err := recover(); err != nil {
        // get error message from "err" as string
    }
}()

panic("Fake error!")
3
  • 1
    Out of curiosity, why do you need the error in a []byte? My only guess is that you want to write it to a file, and io.Writer takes in a []byte. If so, there are easier interfaces that take in strings. Commented Sep 27, 2014 at 20:09
  • What do you mean? And yes I'm writing to os.Stderr and a file Commented Sep 27, 2014 at 20:16
  • 1
    Use fmt.Fprint[ln|f](io.Stderr, "my string") In fact, you can substitute my answer with fmt.Fprintf(io.Stderr, "%s%v\n", prefix_err, err) Commented Sep 27, 2014 at 20:18

2 Answers 2

4

There are two different problems here:

The first problem: The actual error type is actually a built-in interface. To implement it you implement a method on the type func Error() string. So anything with the error type can be converted to a string format by calling its Error function.

The second problem: panic doesn't take in an error, it takes in an interface{}. The recover builtin similarly returns whatever interface{} you passed to panic. In this case, calling Error won't work. Indeed, you didn't pass an error into panic, you passed in a string (which is common).

There are a lot of ways you can get a string from an interface{}, and a big type switch is one. But overall I think the easiest option is

myBytes := []byte(fmt.Sprintf("%s%v", prefix_err, err))

Which will always get a string representation of whatever the interface{} was, calling String() or Error() as necessary, and then convert it into a []byte.

(Minor footnote: it's not considered Go style to use underscores in variable names, use camelCase instead).

Edit:

Since it turns out we had a partial "X Y problem" with the conversion to a []byte to write into an io.Writer. If you want to log this to Stderr, you can instead use fmt.Fprintf(os.Stderr, "%s%v\n", prefix_err, err) or even fmt.Fprintln(os.Stderr, prefix_err, err). Any Fprint will correctly print to any io.Writer, including a logfile.

Sign up to request clarification or add additional context in comments.

Comments

-1

Panics do not always take the type of an Error. In your case you are passing in a string.

panic("Fake Error")

err := recover() // => string (interface)

To recover on an error interface, you need to pass an error

panic(fmt.Errorf("Fake Error!"))

err := recover() // => error (interface)
e := err.(error) // type check
e.Error()        // => string

If you are not quite sure which one you'll get, you can type check when you recover and handle accordingly.

Comments

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.