【问题标题】:Catching Haskell exceptions with gi-gtk and Reactive Banana使用 gi-gtk 和 Reactive Banana 捕获 Haskell 异常
【发布时间】:2018-11-02 13:20:36
【问题描述】:

当然,我的应用程序没有错误,但以防万一它包含任何底部值,我想将其放入通用异常捕获器中,它至少会弹出一个消息框告诉用户要报告哪种错误.因为我使用的是gi-gtk,所以我认为初始化后的任何异常都会在Gtk.main函数内部发生,所以我的main函数的结尾看起来像这样:

let executeProgram =
     catch Gtk.main $ \e -> do
           reportThisBugDialog $ show (e :: SomeException)
           -- Code here to try to recover to a known good state
           executeProgram
executeProgram

我也在使用Reactive Banana 以防万一,但这在 FRP 代码之外。

但是,这不会捕获任何异常。我将error "Test Exception" 放在“Help About”的处理程序中,我的程序刚刚退出,控制台上打印了一条消息(我的用户当然不会看到)。

当我的代码对 GTK 信号做出反应时,我如何捕捉发生在我的代码中的异常?

【问题讨论】:

  • 好问题。我怀疑你将不得不将每个回调包装在一个处理程序中,因为我相信回调会在新的 Haskell 线程中运行(尽管仍然与 main 在同一个操作系统线程上,假设 Gtk.main 本身是)。你能检查一下这是否适合你吗? (我知道这很糟糕......)
  • @DanielWagner 实际上比这更糟糕:几乎我所有的回调都只是触发 Reactive Banana 事件。在调用堆栈和异常处理方面接下来会发生什么我不确定。

标签: haskell gtk3 frp


【解决方案1】:

有类似的问题here(虽然它不是针对gi-gtk,所以更笼统)t。我也推荐this 发帖。

基本上,haskell 异常不能通过 haskell/C 边界。仅仅是因为 C 对 haskell 异常一无所知。

在您的情况下,Gtk.main 运行gtk 事件循环,该循环是用 C 实现的,而回调是用 Haskell 实现的。当回调抛出haskell异常时,它必须经过gtk事件循环才能到达executeProgram函数。但由于上述原因,这是不可能的。

恐怕,解决方案是在每个回调中捕获所有异常。在您的情况下,您可能可以在gi-gtk 中为on 函数编写一个包装器,它将捕获所有异常并显示错误对话框。

【讨论】:

  • 感谢您的解释。我会试试你建议的包装器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 2015-06-11
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
相关资源
最近更新 更多