Search code examples
c++gtkmm3

Is it OK to create Gtk::Builder from resource without implementing try/catch block?


Gtk::Builder::create_from_resource() throws the following exceptions when something goes wrong, for instance, the resource file wasn't found or there's a markup error in the Glade/UI file, etc

  • BuilderError
  • Glib::MarkupError
  • Gio::ResourceError

But I don't have any intention to handle those exceptions and do something else in my GTKMM program.

In case, if I have to implement try/catch block out of good programming practice, bare basic code would look like this:

try {
    auto resource = Gtk::Builder::create_from_resource("/domain/reverse/myappid");
} catch (const Gio::ResourceError &ex) {
    cerr << ex.what();
} catch (const Glib::MarkupError &ex) {
    cerr << ex.what();
} catch (const Gtk::BuilderError &ex) {
    cerr << ex.what();
}

I'm just printing the same exception message if any one of them was thrown... But anyway even without implementing the try/catch block, I still get the same meaningful message. And in both cases, the program would run just fine, no application crashes intended. Just the info printed on console for developers.

So is it safe to write less and readable code without the try/catch block for Gtk::Builder::create_from_resource?


Solution

  • If you really don't want to handle the exception, the program will simply terminate abruptly if some exception is thrown.

    I personally prefer to use global exception handling in these cases. In your case, all exceptions derive from std::exception or Gtk::BuilderError, so your handler could look like:

    int main()
    {
        try
        {
            // Program code, eventually a call to `Gtk::Builder::create_from_resource`.
        }
        catch(const std::exception& p_exception)
        {
            cerr << p_exception.what();
        }
        catch(const Gtk::BuilderError& p_exception)
        {
            cerr << p_exception.what();
        }
    
        return 0;
    }
    

    What I like about this is that I don't have to put try-catch blocks everywhere for exceptions I have no intention of handling (ex.: the user somehow revoved the ressource file), but I can log something for debug purposes, or warn the user instead of simply crashing (i.e terminating).

    You could also use the catch-all syntax:

    int main()
    {
        try
        {
            // Program code, eventually a call to `Gtk::Builder::create_from_resource`.
        }
        catch(...)
        {
            // Do something, but the exception message is not available.
        }
    
        return 0;
    }
    

    This has the advantage of catching everything (even exceptions that are not child classes of std::exception), but has the disadvantage that you loose the exception message, as least for standard C++.