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

2022-05-05 18:13:16 +08:00
 dzdh

比如有个三方包

package third

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

然后我调用

package main

import third

func main() {
    callX()
}

func callX() error {
    //thrid.X() 这里会 panic ,怎么拿到当做 error 返回
}
2438 次点击
所在节点    Go 编程语言
17 条回复
jybox
2022-05-05 18:30:56 +08:00
undeflife
2022-05-05 19:00:51 +08:00
bugfan
2022-05-05 22:23:32 +08:00
可以看看 gin 框架是怎么捕获的~
dzdh
2022-05-05 22:26:47 +08:00
@jybox
@undeflife

recover 只能在 defer 里,但是 defer 又没有返回值,怎么能在 callX 方法里把 panic 信息当做 error 返回呢?
phpfpm
2022-05-05 22:33:22 +08:00
@dzdh 再包装一层函数啊。。。
Akkuman
2022-05-05 22:37:06 +08:00
@dzdh 先定义一个 err ,再进行 defer func 里面 recover ,如果有 panic 就赋值到 err 上去,然后函数 return 就会带上你的 err 了
tairan2006
2022-05-05 22:43:03 +08:00
panic 的条件你在外围先判断一次不就完了…
dzdh
2022-05-05 22:51:08 +08:00
@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
2022-05-05 23:04:53 +08:00
@bugfan

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

打个比方说,cli 场景下,进行视频转码,转码失败了,业务还继续,标记转码结果为 fail
icexin
2022-05-05 23:27:36 +08:00
用闭包+工具函数可以达成你的需求 https://gist.github.com/icexin/fd39098dbd8e411d035573d893a46c33
tairan2006
2022-05-05 23:35:33 +08:00
lo.Try

不过要 1.18
soseek
2022-05-06 00:59:37 +08:00
```go
import "github.com/sohaha/zlsgo/zerror"

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

// code

return nil
})

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

```
joesonw
2022-05-06 09:18:41 +08:00
defer xx(&err) 传指针。
dzdh
2022-05-06 10:33:11 +08:00
Juszoe
2022-05-06 10:40:45 +08:00
lo 是泛型工具库 https://github.com/samber/lo
dzdh
2022-05-06 13:28:34 +08:00
@Juszoe 可是只能返回 error ,如果没发生 Panic 的时候,咋获取正确的返回值咧
Akkuman
2022-05-14 15:00:25 +08:00
@dzdh uber 好像有个工具,使用 ast 自动加上,需要用 go generate

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851002

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX