0

I'm experimenting with the concurrent run with promise functionality from Qt6. How can I catch, from the GUI thread, any exception thrown in the worker thread?

void MainWindow::on_pushButton_startTask_clicked()
{
    auto lambda = [](QPromise<void>& promise)
    {
        // Cancel the task if requested
        while (!promise.isCanceled())
        {
            // Do some long computation...

            if (<something-has-failed>)
                throw std::runtime_error("The task has failed");
        }
    };

    this->future = QtConcurrent::run(lambda);
    // Connect the watcher to the finished signal
    connect(&this->watcher, &QFutureWatcher<void>::finished, this, &MainWindow::on_taskFinished);
    this->watcher.setFuture(this->future);
}

void MainWindow::on_taskFinished()
{
    // How to catch the exception here?
}

I've tried by doing the following two things:

  1. Adding onFailed in the on_taskFinished:
void MainWindow::on_taskFinished()
{
    this->future.onFailed([](const std::exception& ex)
    {
        std::cout << ex.what();
    });
}
  1. Adding onFailed after calling QtConcurrent::run:
void MainWindow::on_pushButton_startTask_clicked()
{
    ...

    this->future = QtConcurrent::run(lambda)
        .onFailed([](const std::exception& ex)
        {
            std::cout << ex.what();
        });
    ...
}

In both cases the code passes from the onFailed block, but the exception is not the one thrown from the lambda, it looks like an empty default excetion (maybe something from Qt?), whose what content is Unknown exception.

Rackbox
  • 283
  • 1
  • 11
  • How about using `std::async` and `std::future`? They handle exceptions implicitly. Anyway you should not use exceptions in Qt specific code. – Marek R Apr 20 '23 at 10:49
  • If I used `std::async` I would loose the ability to connect a `QFutureWatcher` to handle the `finished` event, wouldn't I? – Rackbox Apr 20 '23 at 11:42
  • I have never tried but I would think that as long as the receiver lives in a thread with an event loop, sending signals from any thread (including non-Qt threads) should work. You may need to explicitly make the connection a `Qt::QueuedConnection`. – Atmo Apr 20 '23 at 13:49

0 Answers0