代码之家  ›  专栏  ›  技术社区  ›  Saurabh Nanda

如何从某个异常(或任何其他自定义异常)获取stacktrace?

  •  0
  • Saurabh Nanda  · 技术社区  · 5 年前

    今天(GHC 8.8.3+)是否可以从使用 throwIO , throwM 等等。我花了一个多小时看 Control.Exception GHC.Stack 但找不到类型为的函数 SomeException -> CallStack (或类似)。我甚至试过Hoogle,但什么也找不到。

    0 回复  |  直到 5 年前
        1
  •  2
  •   Z-Y.L    5 年前

    正如@李姚霞所说,目前没有办法做你想做的,但有一些工作轮,其中之一是添加 HasCallStack

    import GHC.Stack
    
    head' :: HasCallStack => [a] -> a
    head' [] = error "empty list"
    head' (x:_) = x
    
    foo :: HasCallStack => [a] -> a
    foo xs = head' xs
    
    goo :: HasCallStack => [Int] -> Int
    goo (0:_) = error "Divid by zero"
    goo xs = div 5 (foo xs)
    
    hoo :: HasCallStack => [Int] -> Int
    hoo xs = goo xs + 4
    

    将上述代码加载到 ghci ,您可以跟踪调用堆栈:

    ghci> foo []
    *** Exception: empty list
    CallStack (from HasCallStack):
      error, called at CallStack.hs:4:12 in main:Main
      head', called at CallStack.hs:8:10 in main:Main
      foo, called at <interactive>:14:1 in interactive:Ghci1
    ghci> hoo [0, 1]
    *** Exception: Divid by zero
    CallStack (from HasCallStack):
      error, called at CallStack.hs:11:13 in main:Main
      goo, called at CallStack.hs:15:10 in main:Main
      hoo, called at <interactive>:15:1 in interactive:Ghci1
    

    • 分析: ghc -prof -fprof-auto ghci -fexternal-interpeter -prof
    • 矮子: ghc -g .

    有关更多信息,请参阅 posts

        2
  •  1
  •   Li-yao Xia    5 年前

    这是不可能的,因为 SomeException 不记录异常的跟踪。这实际上是正在进行的GHC提案的主题: https://github.com/bgamari/ghc-proposals/blob/stacktraces/proposals/0000-exception-backtraces.rst

    目前,您必须手动包装异常以捕获跟踪:定义您自己的异常类型,为跟踪留出空间,并定义您自己的抛出函数以捕获跟踪。

    推荐文章