英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论