苦于没有异常,怎么优雅的捕捉三方包里的 panic - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dzdh

苦于没有异常,怎么优雅的捕捉三方包里的 panic

  •  
  •   dzdh 2022 年 5 月 5 日 2989 次点击
    这是一个创建于 1450 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如有个三方包

    package third func X() { panic("error") } 

    然后我调用

    package main import third func main() { callX() } func callX() error { //thrid.X() 这里会 panic ,怎么拿到当做 error 返回 } 
    17 条回复    2022-05-14 15:00:25 +08:00
    jybox
        1
    jybox  
       2022 年 5 月 5 日
    undeflife
        2
    undeflife  
       2022 年 5 月 5 日
    bugfan
        3
    bugfan  
       2022 年 5 月 5 日 via iPhone
    可以看看 gin 框架是怎么捕获的~
    dzdh
        4
    dzdh  
    OP
       2022 年 5 月 5 日
    @jybox
    @undeflife

    recover 只能在 defer 里,但是 defer 又没有返回值,怎么能在 callX 方法里把 panic 信息当做 error 返回呢?
    phpfpm
        5
    phpfpm  
       2022 年 5 月 5 日
    @dzdh 再包装一层函数啊。。。
    Akkuman
        6
    Akkuman  
       2022 年 5 月 5 日 via Android
    @zdh 先定义一个 err ,再进行 defer func 里面 recover ,如果有 panic 就赋值到 err 上去,然后函数 return 就会带上你的 err 了
    tairan2006
        7
    tairan2006  
       2022 年 5 月 5 日 via Android
    panic 的条件你在外围先判断一次不就完了…
    dzdh
        8
    dzdh  
    OP
       2022 年 5 月 5 日
    @phpfpm
    @Akkuman
    @tairan2006


    一定要

    ```go
    func call() (err error) {

    defer func() {
    if r := recover(); r != nil {
    err = errors.New(fmt.Sprint(r))
    }
    }()

    err = errors.New("33")

    panic(111)

    return
    }
    ```

    有没有什么语法糖可以 `defer xx()` 就能实现的,或者有什么全局的『拦截器』之类的吗?
    dzdh
        9
    dzdh  
    OP
       2022 年 5 月 5 日
    @bugfan

    感觉还不一样。gin 是一次请求中的所有『异常』全部都在某一个点进行『捕获』。但是需要的是在某个特定的业务逻辑中需要捕获某个三方包的异常,如果这个三方包异常了,我要做一些处理,然后业务逻辑继续。

    打个比方说,cli 场景下,进行视频转码,转码失败了,业务还继续,标记转码结果为 fail
    icexin
        10
    icexin  
       2022 年 5 月 5 日
    用闭包+工具函数可以达成你的需求 https://gist.github.com/icexin/fd39098dbd8e411d035573d893a46c33
    tairan2006
        11
    tairan2006  
       2022 年 5 月 5 日 via Android
    lo.Try

    不过要 1.18
    soseek
        12
    soseek  
       2022 年 5 月 6 日 via Android
    ```go
    import "github.com/sohaha/zlsgo/zerror"

    err := zerror.TryCatch(func() error {

    // code

    return nil
    })

    // 如果 TryCatch 内返回了 error 或触发了 panic
    if err != nil{
    // ..
    }

    ```
    joesonw
        13
    joesonw  
       2022 年 5 月 6 日 via iPhone
    defer xx(&err) 传指针。
    dzdh
        14
    dzdh  
    OP
       2022 年 5 月 6 日
    Juszoe
        15
    Juszoe  
       2022 年 5 月 6 日
    lo 是泛型工具库 https://github.com/samber/lo
    dzdh
        16
    dzdh  
    OP
       2022 年 5 月 6 日
    @Juszoe 可是只能返回 error ,如果没发生 Panic 的时候,咋获取正确的返回值咧
    Akkuman
        17
    Akkuman  
       2022 年 5 月 14 日 via Android
    @dzdh uber 好像有个工具,使用 ast 自动加上,需要用 go generate
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3012 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 67ms UTC 03:04 PVG 11:04 LAX 20:04 JFK 23:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86