在Golang中定制错误对象

error type

Go语言中的默认错误对象是error,然而它只能包含一个字符串,如果想让它包含更多的结构化信息,就需要定制一个对象。

Go中的error是一个接口类型。

type error interface {
    Error() string
}

fmt包会调用Error() string方法来打印错误。

实现String()方法

package main

import (
	"errors"
	"fmt"
)

// CusErr is custom error object
type CusErr struct {
	Status int
	Err    error
}

func (cusErr *CusErr) String() string {
	return fmt.Sprintf("%s ,%d", cusErr.Err, cusErr.Status)
}

func main() {

	cus := &CusErr{10, errors.New("abc error")}
	fmt.Println(cus)

	cus2 := testErr()
	fmt.Println(cus2)

}

// if it returns error object, the built-in error's interface will not be satisfied.
// It needs Error() function.
func testErr() *CusErr {
	return &CusErr{1, errors.New("test error")}
}

output

abc error ,10
test error ,1

实现Error()方法,使其符合error接口

package main

import (
	"errors"
	"fmt"
)

// CusErr is custom error object
type CusErr struct {
	Status int
	Err    error
}

func (cusErr *CusErr) Error() string {
	return fmt.Sprintf("msg: %s ,code: %d", cusErr.Err, cusErr.Status)
}

func main() {

	cus := &CusErr{10, errors.New("abc error")}
	fmt.Println(cus)

	cus1 := testErr1()
	fmt.Println(cus1)

	cus2 := testErr2()
  fmt.Println(cus2)
  
  if cuserr, ok := cus2.(*CusErr); ok {
		fmt.Println("status:", cuserr.Status)
	}
}

func testErr1() *CusErr {
	return &CusErr{1, errors.New("test error")}
}

func testErr2() error {
	return &CusErr{2, errors.New("test error")}
}

output

msg: abc error ,code: 10
msg: test error ,code: 1
msg: test error ,code: 2
status: 2

Resources