首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何抑制Go中`panic`后的堆栈跟踪?

如何抑制Go中`panic`后的堆栈跟踪?
EN

Stack Overflow用户
提问于 2020-07-20 01:47:12
回答 1查看 389关注 0票数 0

我正在开发一个CLI工具,在出现问题的情况下,我希望记录自定义错误,并带着恐慌退出。死机的问题是,panic退出之后是堆栈跟踪,我不想向用户显示它。有没有一种方法可以让你惊慌失措,拥有一个忍者般的隐秘/安静的出口?

(选择panic而不是os.Exit(),因为它可以处理任何defer,而且看起来干净多了。)

EN

回答 1

Stack Overflow用户

发布于 2020-07-20 02:24:59

嗯,一个直接的答案是肯定的,有一种方法:

如果出现自定义" sentinel“类型的错误,或者带有自定义的" sentinel”值,则

  • main中有一个defer-red调用,该调用recover()-s死机并检查返回的值是否为sentinel类型(或等于sentinel值-具体方法由您决定)。

如果它检测到“已知”错误,它将静默退出,并返回非零退出代码;否则,它将再次panics。

但老实说,我认为你的心态太受编程语言的影响了,但也有例外:我还没有看到一个CLI应用程序在“通常的方式”处理错误时会有任何困难,或者实际上可以从使用panic中受益。

与您渴望的方法相反的一个论点是:冒泡错误允许在展开的调用堆栈的每个级别上向其添加更多上下文,这是有意义的,-producing尽可能有用地显示错误。基本上,它是这样工作的:

代码语言:javascript
复制
func main() {

  ...

  err := DoStuff()
  if err != nil {
    log.Fatal("failed to do stuff: ", err)
  }

  ...
}

func DoStuff() error {
  foo, err := InitializeWhatever()
  if err != nil {
    return fmt.Errorf("failed to inialize whatever: %w", err)
  }

  ...

  return nil
}

func InitializeWhatever() (*Whatever, error) {
  handle, err := OpenWhateverElse()
  if err != nil {
    return nil, fmt.Errorf("failed to open whatever else: %w", err)
  }

  ...

  return whatever, nil
}

…它会产生类似这样的结果

failed to do stuff: failed to inialize whatever: failed to open whatever else: task failed successfully

…这清楚地表明了是哪一系列事件导致了不希望看到的结果。

当然,和往常一样,YMMV,除了你之外,没有人最了解你的情况,但它仍然是值得思考的事情。

这里是我在上面写的各种想法的列表。

  • 使用已知类型的已知值/错误的方法实际上并不是什么新鲜事-例如,参见net/http.ErrAbortHandler

用于使用这种方法来打破多个嵌套循环的encoding/json包(自那以后已经被修改,一些专家consider sentinel errors to be bad design并建议改为断言(使用Go的类型断言)错误的行为-例如,您可以查看net.Error如何具有TimeoutTemporary方法,这些方法允许暂时错误和由于超时而导致的错误及其组合没有具体的导出类型。相反,-but让它们都支持一组通用的方法,这些方法允许调用者理解错误的nature.

  • Since 1.13,Go gained高级支持“包装”错误-生成matryoshka风格的错误链,这允许一种介于上述两个极端之间的错误处理方法:一个人可以在第一次发现错误的地方创建一个特定类型的错误,然后当它们在调用堆栈中冒泡时将其包装在上下文中,然后在处理错误的位置断言最内部错误的类型。A friendly explanation on how it works.

嗯,我推荐阅读this,因为我必须承认,如果你已经这样做了,你很可能一开始就不会问你的问题;-)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62983700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档