Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-5064

Exceptions from slots

XMLWordPrintable

    • Icon: Suggestion Suggestion
    • Resolution: Out of scope
    • Icon: P4: Low P4: Low
    • None
    • 4.5.3
    • Core: Object Model
    • None

      I'm glad someone reads this after taking a glance at the summary - I suspect you might get this a lot. But as I believe that I have a point here I'll still post this:

      As we all know Qt itself is not exception-safe (in the sense that an exception which comes from inside Qt will most likely bring down the whole application) - that's fine with me, after all this is your software, not mine (and it probably doesn't make sense to waste time writing exception-safe code if you can't really use exceptions due to supported environments anyway).

      However, as a result this means that throwing an exception from a slot which is connected to a Qt class (in my application I have have MainWindow::on_actionLoadScenario_triggered) has the same effect when using a direct connection (or an auto connection dispatched directly).

      In my particular case I have installed an exception-catching event handler, but when the exception comes from through a particular code path QMenuPrivate::activateCausedStack() raises an assertion failure the next time it's called, because of a static variable used to check for recursion.

      Now, I understand that you wouldn't consider this a bug - after all you don't claim that QMenu is exception-safe... but QT_NO_EXCEPTIONS exists and QMetaObject::activate() behaves differently if it's not defined - so - why not allow the user to register an exception handler, along the lines of:

      bool userExceptionHandler(); // if true the exception is ignored

      try {
      receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
      } catch (...) {
      ...
      if(userExceptionHandler && userDefinedExceptionHandler())
      continue;
      throw;
      }

      I suppose it would be nice if the handler would also get information about the sender, received, slot and signal.

      That user-defined function would then rethrow/recatch the exception, check whether it knows about it, and if it's a "harmless" exception (say connection failure) go on dispatching to the next slot.

      Another option would be to break out of the dispatcher loop but I believe this makes much more sense - either the exception is to be ignored by the caller, in which case other slots should still be serviced, or the caller must be notified about the fact that some slots might not have gotten the information.

      If you believe breaking out of the loop and skipping slots might actually be desirable (the only reason I can think of would be compatibility to the current behavior of an exception being thrown from a slot served through a queued connection) I'd vote for a three-way selection by the callback - "throw, continue, break".

      For my application I will add this hack to my local Qt for now (we link statically) - the alternative would be to add try/catch/log+ignore clauses around a lot of slots (we have lots of CORBA calls attached to GUI signals - the slot itself is written exception-safe using RAII, an ORB exception handler ensures that the proper action will be taken - the only problem currently is that the exception disrupts Qt...).

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            ogoffart Olivier Goffart (Woboq GmbH)
            fnawothnig Felix Nawothnig
            Votes:
            3 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes