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

Support dealing with unhandled exceptions from signal callbacks #845

Open
cameronwhite opened this issue Apr 1, 2023 · 4 comments
Open
Milestone

Comments

@cameronwhite
Copy link
Contributor

In GtkSharp, the bindings caught any unhandled exceptions from callbacks (e.g. https://github.com/GtkSharp/GtkSharp/blob/c6a2696d2288375c43486ba7ae2018ed027b16c5/Source/Libs/GLibSharp/SignalClosure.cs#L181 and https://github.com/GtkSharp/GtkSharp/blob/develop/Source/Libs/GLibSharp/ExceptionManager.cs) and raised an event that allowed the application to log or display errors
(Example from Pinta: https://github.com/PintaProject/Pinta/blob/5428fa04d3ca4562980e702b1bc568f9ec0b1bb7/Pinta/Main.cs#L137)

Otherwise, it seems like these unhandled exceptions will just terminate the program once they hit the native code boundary that invoked the delegate, so an outer try/catch block around application.Run() doesn't seem to work

Example program:

using System;

void HandleClick(Gtk.Button sender, System.EventArgs args)
{
    throw new System.NotImplementedException();
}

var application = Gtk.Application.New("org.gir.core", Gio.ApplicationFlags.FlagsNone);
application.OnActivate += (sender, args) =>
{
    var window = Gtk.ApplicationWindow.New((Gtk.Application) sender);
    window.Title = "Gtk4 Window";
    window.SetDefaultSize(300, 300);

    var button = Gtk.Button.NewWithLabel("Press me");
    button.OnClicked += HandleClick;
    window.SetChild(button);

    window.Show();
};

try
{
    return application.Run();
}
catch (Exception e)
{
    System.Console.WriteLine("unhandled exception {0}", e);
}

return 1;
@badcel badcel added this to the 0.8.0 milestone Apr 2, 2023
@badcel
Copy link
Member

badcel commented Apr 17, 2023

This probably affects regular callbacks, too.

@cameronwhite
Copy link
Contributor Author

yep, I think it probably applies for any delegates that get passed into and then called by native code

cameronwhite added a commit that referenced this issue Apr 30, 2023
…e code

These unhandled exceptions would otherwise immediately terminate the program once they reach the native code boundary. This event lets applications do any logging / message dialogs etc and decide whether they want to terminate the program or attempt to continue.

Bug: #845
cameronwhite added a commit that referenced this issue May 1, 2023
…e code

These unhandled exceptions would otherwise immediately terminate the program once they reach the native code boundary. This event lets applications do any logging / message dialogs etc and decide whether they want to terminate the program or attempt to continue.

Bug: #845
@badcel
Copy link
Member

badcel commented May 2, 2023

Fixed for signal callbacks in #861

cameronwhite added a commit that referenced this issue May 3, 2023
This is good to have in general, but is also needed for #845 where we want to test exception handling for callbacks

Callbacks with `notified` scope are the only type that currently has full support for generating public bindings
@cameronwhite
Copy link
Contributor Author

One thing that I noticed in #862 is that return types (or out parameters) add some complexity for exception handling in callbacks. Since the exception is swallowed and then control returns to the native function, the native code needs to have a valid return value since it's proceeding as usual.
So, we probably need to set the return value to some default value if the managed callback has an unhandled exception

In GtkSharp, it looks like they just did this for bool return types (and void, of course), but if there was any other return type, or an out parameter, they just gave up and treated the unhandled exception as a fatal error and terminated.

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