type error interface {
Error() string
}
内建error接口类型是约定用于表示错误信息,nil值表示无错误。
package errors
import “errors”
errors包实现了创建错误值的函数。
package main
import (
"fmt"
"time"
)
// MyError is an error implementation that includes a time and message.
type MyError struct {
When time.Time
What string
}
func (e MyError) Error() string { // 实现了Error接口
return fmt.Sprintf("%v: %v", e.When, e.What)
}
func oops() error {
return MyError{
time.Date(1989, 3, 15, 22, 30, 0, 0, time.UTC),
"the file system has gone away",
}
}
func main() {
if err := oops(); err != nil {
fmt.Println(err)
}
}
运行结果:1989-03-15 22:30:00 +0000 UTC: the file system has gone away
func New(text string) error
使用字符串创建一个错误,请类比fmt包的Errorf方法,差不多可以认为是New(fmt.Sprintf(…))。
package main
import (
"errors"
"fmt"
)
func main() {
err := errors.New("emit macho dwarf: elf header corrupted")
if err != nil {
fmt.Print(err)
}
}
运行结果:emit macho dwarf: elf header corrupted
package main
import (
"fmt"
)
func main() {
const name, id = "bimmler", 17
err := fmt.Errorf("user %q (id %d) not found", name, id)
if err != nil {
fmt.Print(err)
}
}
运行结果:user “bimmler” (id 17) not found
fmt.Errorf 和 errors.New的返回值
package main
import (
"errors"
"fmt"
)
func test1() error {
return fmt.Errorf("aaaaa")
}
func test2() error {
return errors.New("bbbbb")
}
func main() {
err := test1()
fmt.Printf("%T : %v\n", err, err)
err = test2()
fmt.Printf("%T : %v\n", err, err)
}
运行结果:
*errors.errorString : aaaaa
*errors.errorString : bbbbb
对error信息进行封装
package main
import (
"errors"
"fmt"
"strings"
)
type decodeError struct {
what error
stack []string
}
func wrapError(err error, ctx string) error {
if err == nil {
return nil
}
// 如果传入的类型为 decodeError 将其内容追加到 stack 里
if decErr, ok := err.(*decodeError); ok {
decErr.stack = append(decErr.stack, ctx)
return decErr
}
// 如果传入的err类型不是decodeError类型,将其保存为decodeError类型
return &decodeError{err, []string{ctx}}
}
// 实现error的 Error 接口,该接口会在fmt.Println的时候调用。
// err.what 保存了 errors.New 的错误信息。
// strings.Join 是将 err.stack 中的字符串用 <- 连接起来。
func (err *decodeError) Error() string {
return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-"))
}
func test() error {
return errors.New("aaaaa")
}
func main() {
err := test()
err = wrapError(err, "mmmmm")
err = wrapError(err, "nnnnn")
err = wrapError(err, "lllll")
fmt.Println(err)
}
运行结果:aaaaa (decode path: mmmmm<-nnnnn<-lllll)