最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go使用errors.Wrapf()代替log.Error()方法示例

 更新時間:2023年08月31日 11:02:46   作者:好文收藏  
這篇文章主要為大家介紹了go使用errors.Wrapf()代替log.Error()的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

介紹不同語言的錯誤處理機制:

Error handling patterns

Musings about error handling mechanisms in programming languages

項目中 main調(diào)func1,func1調(diào)取func2...

這樣就會出現(xiàn)很多的 if err != nil { log.Printf()} , 在Kibana上查看時會搜到多條日志, 需要逐級定位, 確定錯誤拋出的點

希望只有一條, 能清晰看到整個堆棧調(diào)用信息

使用log.xxxx方法

package main
import (
    "fmt"
    "log"
    "strconv"
    "time"
)
func init() {
    log.SetFlags(log.Lshortfile | log.LstdFlags)
}
func main() {
    str := "123a"
    rs, err := func1(str)
    if err != nil {
        log.Printf("err is (%+v)\n", err)
        return
    }
    fmt.Println("最終結果為:", rs)
}
func func1(str string) (int, error) {
    b, err := func2()
    if err != nil {
        log.Printf("There is func11111,  func2 err(%+v)\n", err)
    }
    if b == false {
        strInt, err := strconv.Atoi(str)
        if err != nil {
            log.Printf("There is func11111, err(%+v)\n", err)
        }
        return strInt, err
    }
    return 0, nil
}
func func2() (bool, error) {
    now := time.Now().Unix()
    endTimeStr := "2021-08-06 20:00:0000"
    endtime, err := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local)
    if err != nil {
        log.Printf("There is func22222, err(%+v)\n", err)
        return false, err
    }
    if endtime.Unix() > now {
        return true, nil
    }
    return false, nil
}

執(zhí)行結果:

2021/06/07 21:52:56 vs.go:56: There is func22222, err(parsing time "2021-08-06 20:00:0000": extra text: "00")
2021/06/07 21:52:56 vs.go:33: There is func11111,  func2 err(parsing time "2021-08-06 20:00:0000": extra text: "00")
2021/06/07 21:52:56 vs.go:40: There is func11111, err(strconv.Atoi: parsing "123a": invalid syntax)
2021/06/07 21:52:56 vs.go:20: err is (strconv.Atoi: parsing "123a": invalid syntax)

使用errors.Wrapf方法

package main
import (
    "fmt"
    "github.com/pkg/errors"
    "strconv"
    "time"
)
func main() {
    str := "123a"
    rs, err := func1(str)
    if err != nil {
        fmt.Printf("err: %+v\n", err)
        //fmt.Println("err:", lastErr) //必須%+v才會打印完整堆棧信息,否則只打印錯誤信息
        return
    }
    fmt.Println("最終結果為:", rs)
}
func func1(str string) (int, error) {
    b, err := func2()
    if err != nil {
        err = errors.Wrapf(err, "There is func11111, func2 err, b is(%b) \n", b)
    }
    if b == false {
        var strInt int
        strInt, err = strconv.Atoi(str)
        if err != nil {
            err = errors.Wrapf(err, "There is func11111,str is(%s)\n", str)
        }
        return strInt, err
    }
    return 0, nil
}
func func2() (bool, error) {
    now := time.Now().Unix()
    endTimeStr := "2021-08-06 20:00:0000"
    endtime, err := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local)
    if err != nil {
        err = errors.Wrapf(err, "There is func22222,endTimeStr is(%s)\n", endTimeStr)
        return false, err
    }
    if endtime.Unix() > now {
        return true, nil
    }
    return false, nil
}

執(zhí)行:

err: strconv.Atoi: parsing "123a": invalid syntax
There is func11111,str is(123a)
main.func1
        /Users/fliter/go/src/shuang/llog/1.go:39
main.main
        /Users/fliter/go/src/shuang/llog/1.go:13
runtime.main
        /usr/local/Cellar/go/1.16.3/libexec/src/runtime/proc.go:225
runtime.goexit
        /usr/local/Cellar/go/1.16.3/libexec/src/runtime/asm_amd64.s:1371

注意賦值這步, 必不可少!

有一個問題, 即對于f1調(diào)f2,f2調(diào)f3這種, 如果f3發(fā)生error, 可以逐級將error拋出.
但如果一個方法里有兩個error, 則第二條會覆蓋掉第一條,如上 err = errors.Wrapf(err, "There is func11111, func2 err, b is(%b) \n", b)這一條就被覆蓋了

// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is called, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
    if err == nil {
        return nil
    }
    err = &withMessage{
        cause: err,
        msg:   fmt.Sprintf(format, args...),
    }
    return &withStack{
        err,
        callers(),
    }
}
func callers() *stack {
    const depth = 32
    var pcs [depth]uintptr
    n := runtime.Callers(3, pcs[:])
    var st stack = pcs[0:n]
    return &st
}
// Callers fills the slice pc with the return program counters of function invocations
// on the calling goroutine's stack. The argument skip is the number of stack frames
// to skip before recording in pc, with 0 identifying the frame for Callers itself and
// 1 identifying the caller of Callers.
// It returns the number of entries written to pc.
//
// To translate these PCs into symbolic information such as function
// names and line numbers, use CallersFrames. CallersFrames accounts
// for inlined functions and adjusts the return program counters into
// call program counters. Iterating over the returned slice of PCs
// directly is discouraged, as is using FuncForPC on any of the
// returned PCs, since these cannot account for inlining or return
// program counter adjustment.
func Callers(skip int, pc []uintptr) int {
    // runtime.callers uses pc.array==nil as a signal
    // to print a stack trace. Pick off 0-length pc here
    // so that we don't let a nil pc slice get to it.
    if len(pc) == 0 {
        return 0
    }
    return callers(skip, pc)
}
func callers(skip int, pcbuf []uintptr) int {
    sp := getcallersp()
    pc := getcallerpc()
    gp := getg()
    var n int
    systemstack(func() {
        n = gentraceback(pc, sp, 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0)
    })
    return n
}

參考:

golang 打印error的堆棧信息

Go錯誤處理最佳實踐

以上就是go使用errors.Wrapf()代替log.Error()方法示例的詳細內(nèi)容,更多關于go errors.Wrapf log.Error的資料請關注腳本之家其它相關文章!

相關文章

  • 使用Go語言編寫一個NTP服務器的流程步驟

    使用Go語言編寫一個NTP服務器的流程步驟

    NTP服務器【Network?Time?Protocol(NTP)】是用來使計算機時間同步化的一種協(xié)議,為了確保封閉局域網(wǎng)內(nèi)多個服務器的時間同步,我們計劃部署一個網(wǎng)絡時間同步服務器(NTP服務器),本文給大家介紹了使用Go語言編寫一個NTP服務器的流程步驟,需要的朋友可以參考下
    2024-11-11
  • golang 設置web請求狀態(tài)碼操作

    golang 設置web請求狀態(tài)碼操作

    這篇文章主要介紹了golang 設置web請求狀態(tài)碼操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang?sync.Cond同步機制運用及實現(xiàn)

    golang?sync.Cond同步機制運用及實現(xiàn)

    在?Go?里有專門為同步通信而生的?channel,所以較少看到?sync.Cond?的使用,不過它也是并發(fā)控制手段里的一種,今天我們就來認識下它的相關實現(xiàn),加深對同步機制的運用
    2023-09-09
  • golang中值類型/指針類型的變量區(qū)別總結

    golang中值類型/指針類型的變量區(qū)別總結

    golang的值類型和指針類型receiver一直是大家比較混淆的地方,下面這篇文章主要給大家總結介紹了關于golang中值類型/指針類型的變量區(qū)別的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2017-12-12
  • golang類型轉換之interface轉字符串string簡單示例

    golang類型轉換之interface轉字符串string簡單示例

    在我們使用Golang進行開發(fā)過程中,總是繞不開對字符或字符串的處理,這篇文章主要給大家介紹了關于golang類型轉換之interface轉字符串string的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • Golang特殊init函數(shù)的實現(xiàn)實例

    Golang特殊init函數(shù)的實現(xiàn)實例

    本文介紹了Go語言中特殊函數(shù)init()的作用,如變量初始化、包初始化順序以及與main函數(shù)的關系,具有一定的參考價值,感興趣的可以了解一下
    2025-11-11
  • Go語言中Redis緩存與本地內(nèi)存緩存實戰(zhàn)

    Go語言中Redis緩存與本地內(nèi)存緩存實戰(zhàn)

    在現(xiàn)代高并發(fā)系統(tǒng)中,緩存技術是提升性能和降低數(shù)據(jù)庫壓力的關鍵手段,本文將為大家介紹一下Redis緩存與本地內(nèi)存緩存的具體應用,需要的可以了解下
    2025-03-03
  • 深入解析Go語言中for循環(huán)的寫法

    深入解析Go語言中for循環(huán)的寫法

    這篇文章主要介紹了Go語言中for循環(huán)的寫法,是Golang入門學習中的基礎知識,需要的朋友可以參考下
    2015-10-10
  • 淺談Go語言多態(tài)的實現(xiàn)與interface使用

    淺談Go語言多態(tài)的實現(xiàn)與interface使用

    如果大家系統(tǒng)的學過C++、Java等語言以及面向對象的話,相信應該對多態(tài)不會陌生。多態(tài)是面向對象范疇當中經(jīng)常使用并且非常好用的一個功能,它主要是用在強類型語言當中,像是Python這樣的弱類型語言,變量的類型可以隨意變化,也沒有任何限制,其實區(qū)別不是很大
    2021-06-06
  • 十個Go map面試??紗栴}合集

    十個Go map面試??紗栴}合集

    go面試中,map相關知識點問的比較多,這篇文章主要為大家整理歸納了10個??嫉膯栴},文中的示例代碼講解詳細,希望對大家有一定的幫助
    2023-07-07

最新評論

宜阳县| 临沂市| 工布江达县| 黔南| 教育| 怀集县| 武陟县| 灵宝市| 沧州市| 洛川县| 盐源县| 随州市| 犍为县| 永登县| 南木林县| 荣昌县| 恩施市| 义马市| 萨迦县| 永春县| 疏勒县| 上饶县| 黄山市| 兴安县| 铁岭市| 河西区| 巴中市| 高州市| 济阳县| 离岛区| 泽州县| 阳山县| 赤水市| 莱西市| 金乡县| 永善县| 准格尔旗| 江安县| 卫辉市| 家居| 乡城县|