morrisxyang / errors

A simple error library that supports error stacks, error codes, and error chains.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

能支持序列化和反序列化么

mei-rune opened this issue · comments

commented

Hi, 序列化的结果应该是和 fmt.Sprintf("%+v", err) 一致的, 反序列化可能比较复杂, 因为包括堆栈的话是难以反序列化回去的,
能描述下你的具体使用场景和期待结果吗?

commented

我跨进程调用需要这个啊, 我需要它像本地错误一样处理,特别是 多个 error 和 堆栈, 还有 errors.Is() 和 errors.As() 的支持

commented

你这个项目相对 pkg/errors 之类的没有本质的改进, 无非是有后发优势, API 定义更合理。

你实现我上面的需求才能获得更多关注。

这里主要是优化了堆栈的多次生成, 加入了错误码的支持, 自定义堆栈深度, 打印格式等特性.
我主要有2点疑惑:

  1. pkg/errors 确实没有实现完整的序列化和反序列化, 估计是因为原始堆栈信息是无法操作的(底层是一个[]uintptr), 除非是只有打印的那部分string. 但这也就意味着反序列化是不完全的, 无法在另一个进程内反序列化回来当前进程的原始堆栈.
  2. 如果是跨进程调用, 我理解是类似RPC的场景, 一般是使用自定义的协议, 包含code和msg, 针对自己定制的协议进行打包和解包.

不知道我的理解是否有问题, 另外如果能给我一些代码case理解这个诉求就更好了😊

commented
  1. 堆栈一般主要为程序员定位错误发生地点用的, 所以你跨进程时保留 []uintptr 原始信息毫无用处,只要保留 打印的那部分string 就行了。 说实话就算是在同一个进程中,我收到一个 error 时获得其中的 []uintper 有什么用呢,我用它能干什么呢, 我只需要 打印的那部分string 就行了

  2. 是的, 这些 RPC 中 包含code和msg, 这时我需要自定义一个 MyError, 然后再将你的 error 转成 MyError, 在另一个进程中再从 MyError 转成你的 error,不是麻烦么, 我希望你帮我定义一个良好的规范并实现他。

这个 MyError 涉及到很多麻烦的地方

  1. code 这个如何定义, 如保规范
  2. 堆栈如何传递
  3. 多个错误时如何处理, go1.21 支持 errors.Join() 了
  4. errors.Wrap(), errors.Is() 和 errors.Is() 如何处理, 如 errors.Is(err, sql.ErrNoRows) 能实现么。

pkg/errors 能出名是因为发明了 errors.Is() 和 errors.As()
你的增强了 堆栈,但它有多大用处还需要深究,我在日常开发中一般不用 堆栈, 因为在调用 errors.Wrap() 时已经填充了一些信息, 这些信息本身就能定义错误的发生位置。 反过来 errors.WithStack() 一般用于 error 的接收者不调用 errors.Wrap() 时才有用,但这不是 golang 的推荐的方法,golang 希望你认真处理每个 error,而不是仅仅 return err, 最起码写成 return Wrap(err, xxx)。

这也是标库接受 errors.Wrap(), errors.Is() 和 errors.Is() , 却不接受errors.WithStack()堆栈的原因

当然 errors.WithStack() 还是有一些用处的, 当我 panic(err) 时这个 err 最好是 errors.WithStack() 过的

这里确实有很多待定的问题, 尤其是Join后产生的实际是一棵错误树, 对于一棵错误树来讲,堆栈就更复杂了.
给我发封邮件交换下联系方式吧, 需要更快速地交流下.

@mei-rune ok, 我来看一下他的实现, 可能需要一些时间.

commented

最近有没有动作啊