PDA

View Full Version : Catching "wild" exceptions after using QObject::moveToThread



ChiliPalmer
6th July 2015, 17:03
Hi all,

so I have a library consisting of a group of interface classes and a group of internal classes. The internal classes all work in their own, common thread and their methods are called by the interface classes by using
QMetaObject::invokeMethod(implementation, "...", Qt::BlockingQueuedConnection);
The interface classes all move their internal classes into the thread with QObject::moveToThread.
On of the internal classes is a QTcpSocket that tries to recover from different errors and throws an exception if it is unable to recover by itself.
That can happen at any time, not only while calling a method.

So my question is: how can I catch that exception?
I can't put a try catch block into my main method because the exception is thrown by another thread. And I can't catch it within the internal classes because I don't call any of their methods.

anda_skoa
6th July 2015, 18:00
So the internal class throws the exception in some slot that is called via a signal emitted by the thread's event processing?

Why even throw an exception in such a method?

Cheers,
_

ChiliPalmer
6th July 2015, 23:44
Yes. The class containing the socket has a slot connected to the QAbstractSocket::error signal. Under certain conditions that slot throws the exception.

We simply do all error handling with exceptions everywhere we use the library, and the conditions under which the exception is thrown are critical enough to require manual attention.

anda_skoa
7th July 2015, 00:24
So the question becomes: why are you thrown an exception that you cannot catch?

Wouldn't it be better to signal the main thread that an error occurred that needs the attention of code in the main thread?

Or is it that you don't have any control of the code throwing the exception?
In which case it would probably be best to catch it right there in the slot and the signal the main thread.

Cheers,
_

ChiliPalmer
7th July 2015, 18:26
Well, that was my question - is there a way to catch that exception? ;)
If not I will have to think of another solution, of course. But I was hoping there would be a way to catch such an exception anywhere inside or outside the internal classes' thread.

anda_skoa
7th July 2015, 19:41
Well, you can probably catch it in a try-catch block around the thread's exec() call.

But you still need to notify the main thread about it in some way, so I don't see why you can't do it right there when the error occurs.

Cheers,
_

wysota
7th July 2015, 20:58
Well, you can probably catch it in a try-catch block around the thread's exec() call.

But you still need to notify the main thread about it in some way, so I don't see why you can't do it right there when the error occurs.
If an exception is thrown during event processing, Qt will catch it itself and complain about it. A try-catch block around exec() might not work here.

ChiliPalmer
7th July 2015, 21:51
The thread doesn't do anything itself. It's just a common thread for all the internal classes to be moved into. I only use QThread::start(), so I don't call exec directly. I tried putting start into a try catch block, but that didn't work - the exception never got that far.


If an exception is thrown during event processing, Qt will catch it itself and complain about it.

How does Qt complain? Perhaps I could use that.

wysota
8th July 2015, 00:18
How does Qt complain? Perhaps I could use that.

It spits out a warning on a console that you shouldn't be throwing exceptions as part of event processing.

anda_skoa
8th July 2015, 09:26
The thread doesn't do anything itself. It's just a common thread for all the internal classes to be moved into. I only use QThread::start(), so I don't call exec directly.

Well, obviously that would require to implement run() such that you call exec()

Cheers,
_

ChiliPalmer
8th July 2015, 09:58
Well, obviously that would require to implement run() such that you call exec()

Cheers,
_

Completely true. I didn't think of the fact that start works in the main thread, run within the thread.
If anyone is interested: I was able to catch the exceptions by subclassing QThread and putting a try catch block into QThread::run.