1

I tried to break down my problem to a small example. The real problem is a more complex communication:

I have a function that triggers a communication and connects and sends messages to a server. If there is an answer, the Client-class emits a signal containing the answer.

void communicate()
{
     client.setUpMessage(); // the answer is emitted as a signal and
                            // and processed in the Slot 
                            // 'reactToAnswer(...)'

     client.sendMessage("HelloWorld");
}

void reactToAnswer(QString answer)
{
     parser.parseAnswer() // an error could occur
}

What if an error is detected in the slot in which the response is processed? I would like to stop the execution of the function communicate(). This means that the function client.sendMessage("HelloWorld") should no longer be executed.

In my naivety I tried to handle the problem with exceptions:

void communicate()
{
     try
     {
          client.setUpMessage(); // the answer is emitted as a signal and
                                 // and processed in the Slot 
                                 // 'reactToAnswer(...)'

          client.sendMessage("HelloWorld");
      }
      catch(myException)
      {
           // do something
      }

void reactToAnswer(QString answer)
{
     if( !parser.parseAnswer() )
     {
          throw myException;
     }
}

This does not work, throwing an exception from a slot invoked by a qt-signal is undefined behaviour. The usual way is to reimplement QApplication::notify() resp. QCoreApplication()::notify, but this does not work for me. There is already a QApplication for the GUI and I want the communication class (QObject) to stand alone. All things should be treated within this class.

I hope I explained the problem comprehensibly. I do not want to use exceptions in any case, other ways to stop the communication are also right for me.

Thanks in advance!

Community
  • 1
  • 1
Horst
  • 325
  • 3
  • 9
  • Possible duplicate of [Qt C++ QException issue : debug error](http://stackoverflow.com/questions/19144397/qt-c-qexception-issue-debug-error) – cbuchart May 12 '17 at 15:06
  • @KubaOber Thank you for your comment, but this does not work for me. I edited the description and explained whats different in my case. – Horst May 15 '17 at 05:43
  • I guess [this question](http://stackoverflow.com/q/32486198/1329652) is much closer to what you're after, then. – Kuba hasn't forgotten Monica May 15 '17 at 14:02

1 Answers1

1

I'm not sure that what you are trying to accomplish is a particularly good fit for the signals-and-slots paradigm... perhaps you want to go with just a regular old function call instead? i.e. something like:

void communicate()
{
   QString theAnswer;  // will be written to by setupMessage() unless error occurs
   if (client.setUpMessage(theAnswer)) 
   {
      reactToAnswer(theAnswer);     
      client.sendMessage("HelloWorld");
   }
}

The reason that signals-and-slots aren't a good fit is that signals are designed to be connectable to multiple slots at once, and the order in which the slots-methods are called is undefined -- so if a slot-method tries to interfere with the signal-emitting process in the way you describe, the behavior is rather unpredictable (because you don't know how many other connected slot-methods, if any, had already been called as part of the signal-emission, before your particular slot-method hit the brakes). And of course if you ever go to queued/asynchronous signals, then it won't work at all, because the slot will be called in a different context entirely, long after the signal-emitting function has already returned.

That said, if you absolutely must use signals-and-slots for this, you can have your slot emit its own error-has-occurred signal, which can be connected back to a slot in the original signal-emitting class. That slot could then set a boolean (or whatever), and your communicate() method could then check the state of that boolean (right after client.setUpMessage() has returned) to decide whether or not to continue executing or return early.

(I don't recommend that though -- signals-and-slots are there to make your program less complicated, and in this case I think using them instead of a regular function call actually makes your program more complicated, with no corresponding benefit)

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234