从错误接口获取错误字符串。

huangapple go评论82阅读模式
英文:

get error as string from error interface

问题

如何从错误接口中获取错误字符串?

我想将ERROR: Fake error!赋值给一个变量,然后将其转换为切片[]byte(error_str)

prefix_err := "ERROR:"

defer func() {
    if err := recover(); err != nil {
        // 将 "err" 中的错误消息作为字符串获取
    }
}()

panic("Fake error!")
英文:

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!")

答案1

得分: 4

这里有两个不同的问题:

第一个问题:实际上,error类型是一个内置接口。要实现它,你需要在类型上实现一个方法func Error() string。因此,任何具有error类型的内容都可以通过调用其Error函数将其转换为字符串格式。

第二个问题:panic不接受一个error,而是接受一个interface{}。类似地,recover内置函数返回你传递给panic的任何interface{}。在这种情况下,调用Error是行不通的。实际上,你没有将一个error传递给panic,而是传递了一个string(这是常见的)。

有很多方法可以从interface{}获取一个string,其中一个方法是使用类型切换。但总的来说,我认为最简单的选项是:

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

这将始终获得interface{}的字符串表示形式,根据需要调用String()Error(),然后将其转换为[]byte

(小注:在变量名中使用下划线在Go语言中不被认为是一种风格,应该使用驼峰命名法代替)。

编辑:

由于事实证明我们在将其转换为[]byte以写入io.Writer时存在部分“X Y问题”。如果你想将其记录到Stderr,你可以使用fmt.Fprintf(os.Stderr, "%s%v\n", prefix_err, err)或甚至fmt.Fprintln(os.Stderr, prefix_err, err)。任何Fprint都可以正确地打印到任何io.Writer,包括日志文件。

英文:

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.

答案2

得分: -1

恐慌并不总是以错误的形式出现。在你的情况下,你传递了一个字符串。

panic("Fake Error")

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

要在错误接口上进行恢复,你需要传递一个错误。

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

err := recover() // => error (interface)
e := err.(error) // 类型检查
e.Error()        // => string

如果你不确定会得到哪种类型,可以在恢复时进行类型检查,并相应地处理。

英文:

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.

huangapple
  • 本文由 发表于 2014年9月28日 03:49:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/26078558.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定