Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Throwing from QFuture::onFailed()
Forum Updated to NodeBB v4.3 + New Features

Throwing from QFuture::onFailed()

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 538 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Don Burner
    wrote on last edited by
    #1

    Hi,

    I am trying to throw an exception inside QFuture::onFailed()'s lambda, but it appears to catch the exception and presumably propagate it to other chained onFailed() functions that may follow.

    Currently, my workaround is using

    QTimer::singleShot(0, this, []() { throw std::runtime_error("Bye"); });
    

    I am not sure if there is a guaranteed lower/upper-bound in terms of when exactly the singleShot() is executed, but if it happens to execute after onFailed() is done executing, then it successfully crashes the app.

    Is there a better way of achieving this?

    Thanks!

    J 1 Reply Last reply
    0
    • A Offline
      A Offline
      Asperamanca
      wrote on last edited by
      #2

      AFAIK, exceptions through Qt classes or signal/slot connections are not supported.

      1 Reply Last reply
      1
      • A Offline
        A Offline
        Asperamanca
        wrote on last edited by
        #3

        "Throwing an exception from a slot invoked by Qt's signal-slot connection mechanism is considered undefined behaviour, unless it is handled within the slot:"
        See https://doc.qt.io/qt-6/exceptionsafety.html

        1 Reply Last reply
        4
        • D Don Burner

          Hi,

          I am trying to throw an exception inside QFuture::onFailed()'s lambda, but it appears to catch the exception and presumably propagate it to other chained onFailed() functions that may follow.

          Currently, my workaround is using

          QTimer::singleShot(0, this, []() { throw std::runtime_error("Bye"); });
          

          I am not sure if there is a guaranteed lower/upper-bound in terms of when exactly the singleShot() is executed, but if it happens to execute after onFailed() is done executing, then it successfully crashes the app.

          Is there a better way of achieving this?

          Thanks!

          J Offline
          J Offline
          Jeremy Katz at Volexity
          wrote on last edited by
          #4

          @Don-Burner said in Throwing from QFuture::onFailed():

          Hi,

          I am trying to throw an exception inside QFuture::onFailed()'s lambda, but it appears to catch the exception and presumably propagate it to other chained onFailed() functions that may follow.

          Currently, my workaround is using

          QTimer::singleShot(0, this, []() { throw std::runtime_error("Bye"); });
          

          I am not sure if there is a guaranteed lower/upper-bound in terms of when exactly the singleShot() is executed, but if it happens to execute after onFailed() is done executing, then it successfully crashes the app.

          Singleshot versus repeating isn't of significance here. The important detail is that this is a 0 timer.

          https://doc.qt.io/qt-6/qtimer.html#details:
          As a special case, a QTimer with a timeout of 0 will time out as soon as possible, though the ordering between zero timers and other sources of events is unspecified.

          Events are processed by the event loop. Execution timing depends on returning control to the loop, other events in the queue, and what processing those events involves. It's not a realtime oriented system.

          Is there a better way of achieving this?

          What's the end goal?

          D 1 Reply Last reply
          0
          • J Jeremy Katz at Volexity

            @Don-Burner said in Throwing from QFuture::onFailed():

            Hi,

            I am trying to throw an exception inside QFuture::onFailed()'s lambda, but it appears to catch the exception and presumably propagate it to other chained onFailed() functions that may follow.

            Currently, my workaround is using

            QTimer::singleShot(0, this, []() { throw std::runtime_error("Bye"); });
            

            I am not sure if there is a guaranteed lower/upper-bound in terms of when exactly the singleShot() is executed, but if it happens to execute after onFailed() is done executing, then it successfully crashes the app.

            Singleshot versus repeating isn't of significance here. The important detail is that this is a 0 timer.

            https://doc.qt.io/qt-6/qtimer.html#details:
            As a special case, a QTimer with a timeout of 0 will time out as soon as possible, though the ordering between zero timers and other sources of events is unspecified.

            Events are processed by the event loop. Execution timing depends on returning control to the loop, other events in the queue, and what processing those events involves. It's not a realtime oriented system.

            Is there a better way of achieving this?

            What's the end goal?

            D Offline
            D Offline
            Don Burner
            wrote on last edited by
            #5

            @Jeremy-Katz-at-Volexity You are right, I should have been clear. In this instance a more readable way could be something like:

             QMetaObject::invokeMethod(this, [future]() mutable { future.waitForFinished(); }, Qt::QueuedConnection);
            

            I suppose there is no mechanism for me to give priority to this lambda in the event loop.

            Either way, the end goal is to simply crash the program. As far as I know, if a QFuture is chained with QFuture::then(), any exception thrown is propagated to QFuture::onFailed(). What's frustrating is that QFuture::onFailed() also catches exceptions thrown within it. This makes it difficult to simply crash the program if we encounter an exception in either QFuture::then() or QFuture::onFailed().

            J 1 Reply Last reply
            0
            • D Don Burner

              @Jeremy-Katz-at-Volexity You are right, I should have been clear. In this instance a more readable way could be something like:

               QMetaObject::invokeMethod(this, [future]() mutable { future.waitForFinished(); }, Qt::QueuedConnection);
              

              I suppose there is no mechanism for me to give priority to this lambda in the event loop.

              Either way, the end goal is to simply crash the program. As far as I know, if a QFuture is chained with QFuture::then(), any exception thrown is propagated to QFuture::onFailed(). What's frustrating is that QFuture::onFailed() also catches exceptions thrown within it. This makes it difficult to simply crash the program if we encounter an exception in either QFuture::then() or QFuture::onFailed().

              J Offline
              J Offline
              Jeremy Katz at Volexity
              wrote on last edited by
              #6

              @Don-Burner said in Throwing from QFuture::onFailed():

              @Jeremy-Katz-at-Volexity You are right, I should have been clear. In this instance a more readable way could be something like:

               QMetaObject::invokeMethod(this, [future]() mutable { future.waitForFinished(); }, Qt::QueuedConnection);
              

              I suppose there is no mechanism for me to give priority to this lambda in the event loop.

              Nothing simple and straightforward comes to mind.

              Either way, the end goal is to simply crash the program. As far as I know, if a QFuture is chained with QFuture::then(), any exception thrown is propagated to QFuture::onFailed(). What's frustrating is that QFuture::onFailed() also catches exceptions thrown within it. This makes it difficult to simply crash the program if we encounter an exception in either QFuture::then() or QFuture::onFailed().

              Is there a reason to avoid std::abort(), terminate(), exit(), etc?

              D 1 Reply Last reply
              0
              • J Jeremy Katz at Volexity

                @Don-Burner said in Throwing from QFuture::onFailed():

                @Jeremy-Katz-at-Volexity You are right, I should have been clear. In this instance a more readable way could be something like:

                 QMetaObject::invokeMethod(this, [future]() mutable { future.waitForFinished(); }, Qt::QueuedConnection);
                

                I suppose there is no mechanism for me to give priority to this lambda in the event loop.

                Nothing simple and straightforward comes to mind.

                Either way, the end goal is to simply crash the program. As far as I know, if a QFuture is chained with QFuture::then(), any exception thrown is propagated to QFuture::onFailed(). What's frustrating is that QFuture::onFailed() also catches exceptions thrown within it. This makes it difficult to simply crash the program if we encounter an exception in either QFuture::then() or QFuture::onFailed().

                Is there a reason to avoid std::abort(), terminate(), exit(), etc?

                D Offline
                D Offline
                Don Burner
                wrote on last edited by
                #7

                @Jeremy-Katz-at-Volexity said in Throwing from QFuture::onFailed():

                Is there a reason to avoid std::abort(), terminate(), exit(), etc?

                I use std::set_terminate, so unhandled exceptions call my terminate handler.

                Thank you (and @Asperamanca) for the help. I personally think QFuture::onFailed() should not catch exceptions silently. It would not be surprising if other people falsely assume that it doesn't.

                Maybe this can be filed as a Suggestion via the Qt Bug Tracker...

                D 1 Reply Last reply
                0
                • D Don Burner

                  @Jeremy-Katz-at-Volexity said in Throwing from QFuture::onFailed():

                  Is there a reason to avoid std::abort(), terminate(), exit(), etc?

                  I use std::set_terminate, so unhandled exceptions call my terminate handler.

                  Thank you (and @Asperamanca) for the help. I personally think QFuture::onFailed() should not catch exceptions silently. It would not be surprising if other people falsely assume that it doesn't.

                  Maybe this can be filed as a Suggestion via the Qt Bug Tracker...

                  D Offline
                  D Offline
                  Don Burner
                  wrote on last edited by
                  #8

                  @Don-Burner said in Throwing from QFuture::onFailed():

                  I use std::set_terminate, so unhandled exceptions call my terminate handler.


                  EDIT: I thought std::terminate() always called std::abort(). Turns out, it calls the current terminate handler. In short, calling std::terminate() within QFuture::onFailed() works, at least for my purposes. Thanks!

                  1 Reply Last reply
                  1

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved