Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mei-rune opened this issue Jul 6, 2023 · 9 comments
Open

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

mei-rune opened this issue Jul 6, 2023 · 9 comments

Comments

@mei-rune
Copy link

mei-rune commented Jul 6, 2023

No description provided.

@morrisxyang
Copy link
Owner

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

@mei-rune
Copy link
Author

mei-rune commented Jul 6, 2023

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

@mei-rune
Copy link
Author

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

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

@morrisxyang
Copy link
Owner

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

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

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

@mei-rune
Copy link
Author

mei-rune commented Jul 10, 2023

  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() 过的

@morrisxyang
Copy link
Owner

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

@mei-rune
Copy link
Author

@morrisxyang
Copy link
Owner

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

@mei-rune
Copy link
Author

最近有没有动作啊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants