基於golang實現的error工具包

來源:互聯網
上載者:User

寫在前面的話

最近在開發Go項目,發現Go語言本身存在的error並沒有像觸發panic時顯示詳細的調試資訊。對於複雜的系統而言,這會讓我們開發人員需要一定的時間才能定位到錯誤。所以我們基本Go本身的error封裝了一個可以快速定位錯誤工具包。下面讓我們來看看這個工具包是怎麼實現的。

設計思想

  1. 工具包提供ErrErrf兩個完善來登記錯誤,其用法分別類似於fmt.Printfmt.Printf的使用方式,在參數的定義中添加了innerError參數來實現錯誤的傳遞,其值可為nil.
  2. 對外提供StackTrace函數,方便使用者擷取錯誤產生的堆棧資訊。
  3. 通過SetConfig方式實現對錯誤資訊顯示的配置,如在生產環境不需要列印堆棧資訊。通過響應的配置即可關閉。

實現思路

工具包中主要是對堆棧資訊的處理,就是如何才能定位到error的產生位置,通過查看官方文檔,我們發現通過runtime包中的CallersCallersFrames函數可以擷取當前函數調用的堆棧資訊。並且通過Skip參數和自訂過濾條件即可拿到error的產生位置。具體的實現過程如下:

對外提供的2個函數的實現

type Error struct {    err     error    msg     string    fullMsg string    stackTrace}func Errf(err error, format string, args ...interface{}) *Error {    e := &Error{        err: err,        msg: fmt.Sprintf(format, args),    }    e.fullMsg = e.genFullMsg()    return e}func Err(err error, args ...interface{}) *Error {    e := &Error{        err: err,        msg: fmt.Sprint(args),    }    e.fullMsg = e.genFullMsg()    return e}

堆棧資訊的實現

type stackTrace struct {    // stack info    data    string    callers []uintptr}func (err *Error) getStackTrace() string {    if strings.TrimSpace(err.data) == "" {        return err.genStackTrace(5)    }    return err.data}func (err *Error) StackTrace() string {    return err.data}func (err *Error) genStackTrace(skip int) string {    if config.isPrintStack == 1 {        var buffer bytes.Buffer        buffer.WriteString("StackTrace:\n")        var st [64]uintptr        n := runtime.Callers(skip, st[:])        err.callers = st[:n]        frames := runtime.CallersFrames(err.callers)        for {            frame, ok := frames.Next()            if !ok {                break            }            if !strings.Contains(frame.File, "runtime/") {                buffer.WriteString(fmt.Sprintf("%s\n\t%s:%d\n",                 frame.Func.Name(), frame.File, frame.Line))            }        }        err.data = buffer.String()        return err.data    }    return ""}

錯誤資訊顯示配置的實現

const (    //print stack info    PRINTSTACK = 1)// global error config objectvar config *errConfig = &errConfig{}// error configtype errConfig struct {    isPrintStack uint32}//set error config infofunc SetConfig(conf byte) {    if (conf & PRINTSTACK) != 0 {        atomic.CompareAndSwapUint32(&config.isPrintStack, 0, 1)    }}

測試

func init() {    errors.SetConfig(errors.PRINTSTACK)}func main() {    a := func() {        err := errors.Err(nil, "this is an inner error")        fmt.Print(err.StackTrace())        b := errors.Errf(err, "this is a %s message", "test").Error()        fmt.Println(b)    }    a()}

錯誤資訊如下所示

結尾

該工具包只是對error資訊和堆棧資訊的封裝,還存在含多不足的地方。如果各位有好的意見。歡迎指點。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.