Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching Haskell exceptions with gi-gtk and Reactive Banana

Tags:

haskell

frp

gtk3

My application is bug-free, of course, but just in case it contains any bottom values I want to put in a generic exception catcher which will at least pop up a message box to tell the user what kind of bug to report. Because I'm using gi-gtk I figured that any exceptions after initialisation will happen from inside the Gtk.main function, so the end of my main function looks looks something like this:

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

I'm also using Reactive Banana in case that is relevant, but this is outside the FRP code.

However this doesn't capture any exceptions. I put error "Test Exception" in the handler for "Help About", and my program just exited with a message printed to the console (which my users will not see of course).

How do I catch exceptions that occur inside my code when it is reacting to GTK signals?

like image 384
Paul Johnson Avatar asked May 23 '18 13:05

Paul Johnson


1 Answers

There is similar question here (though it is not specific to gi-gtk, so is a bit more general)t. Also I'd recommend this post.

Basically, haskell exceptions can't pass haskell/C border. Simply because C doesn't know anything about haskell exceptions.

In your case, Gtk.main runs gtk event loop, which is implemented in C, and callbacks are implemented in haskell. When callback throws haskell exception, it has to go through gtk event loop in order to reach executeProgram function. But it is impossible for the reason stated above.

I'm afraid, the solution is to catch all exceptions inside each callback. In your case, you probably can write a wrapper over on function from gi-gtk, which will catch all exceptions and show the bug dialog.

like image 99
Yuras Avatar answered Oct 19 '22 05:10

Yuras