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. Catching error thrown in C++ code in Js.
Forum Updated to NodeBB v4.3 + New Features

Catching error thrown in C++ code in Js.

Scheduled Pinned Locked Moved General and Desktop
qjsengine
6 Posts 4 Posters 4.1k Views 4 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.
  • S Offline
    S Offline
    stilgar
    wrote on 21 Mar 2015, 09:06 last edited by stilgar
    #1

    Hello !

    I'm running JS code with QJSEngine. This code calls C++ method, in which errors may occur. I'm looking for a way to get these errors back as a JS exception. Is this possible without having my Q_INVOKABLE methods return error objects and wrapping them in JS functions ?

    class X : public QObject
    {
            Q_OBJECT
        public:
            X(QObject *parent=0);
                Q_INVOKABLE void foo(int arg) {
                if (arg == 0) {
                    // Do something here that causes an exception in the js environment
                    throw "InvalidArgException";
                }
            }
    };
    
    int main(int argc, char *argv[]) {
        QCoreApplication app(argc, argv);
        QJSEngine eng(&app);
        X x(&app);
        eng.globalObject().setProperty("x", eng.newQObject(&x));
        eng.evaluate("try { x.foo(0); } catch(e) { console.log(e); }");
    }
    

    Throwing an exception doesn't work at all, the application is terminated directly without returning to the calling Js environment.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      stilgar
      wrote on 23 Mar 2015, 13:16 last edited by
      #2

      A quick test reveals that it's not possible to use a js proxy to throw the exception.

      If we replace the X::foo() method from my previous post with the following one:

      Q_INVOKABLE void foo(int arg) {
          engine.evaluate("Raiser.raise('foo error')");
      }
      

      And call the following JS code with QJSEngine.evaluate(...):

      var Raiser = {
          raise: function(err) { throw err; }
      };
      try { 
          x.foo();
          console.log("after foo");
      }
      catch (err) {
          console.log("Caught: " + err);
      } 
      

      We get "after foo", not "Caught: foo error". The exception raised in Raiser::raise is cleared before foo() returns.

      The following code found in tests/auto/qml/qqmlecmascript/testtypes.cpp would do the trick, unfortunately, this requires the use of internals. Maybe a method could be added to the QJSEngine public API to wrap engine()->currentContext()->throwError() ?

      void MyQmlObject::v8function(QQmlV4Function *function)
      {
          V8Engine::getV4(function->engine())->currentContext()->throwError(QStringLiteral("Exception thrown from within QObject slot"));
      }
      
      1 Reply Last reply
      1
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 23 Mar 2015, 23:11 last edited by
        #3

        Hi and welcome to devnet,

        To discuss this suggestion, I'd recommend writing to the interest mailing list You'll find there Qt's developers/maintainers (this forum is more user oriented)

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • R Offline
          R Offline
          richardo
          wrote on 20 Apr 2015, 07:34 last edited by richardo
          #4

          I've read that returning an Error object is the way to go, but I've not tried myself. To create one you would have either create one with in Javascript or probably it would do to return one from an failed call of JSEngine::evaluate
          The sole problem is your function would have to return a QJSValue.

          you could try:

          Q_INVOKABLE QJSValue foo(int arg) {
              return engine.evaluate("throw 'foo error'");
          }
          

          or

          Q_INVOKABLE QJSValue foo(int arg) {
              return engine.evaluate("throw new Error('foo error')");
          }
          

          or

          Q_INVOKABLE QJSValue foo(int arg) {
              return engine.globalObject().property("Error").callAsConstructor("foo error");
          }
          

          Let me know if eithere of those worked

          1 Reply Last reply
          0
          • S Offline
            S Offline
            stilgar
            wrote on 30 Apr 2015, 08:26 last edited by
            #5

            Thank you for your answers.

            Richardo, unfortunately none of those work: an error value is returned, not thrown.

            As a workaround I use return values at the moment. I will suggest adding a QJSEngine::throwError() method to the mailing list.

            V 1 Reply Last reply 8 Mar 2018, 19:39
            1
            • S stilgar
              30 Apr 2015, 08:26

              Thank you for your answers.

              Richardo, unfortunately none of those work: an error value is returned, not thrown.

              As a workaround I use return values at the moment. I will suggest adding a QJSEngine::throwError() method to the mailing list.

              V Offline
              V Offline
              VeNToR
              wrote on 8 Mar 2018, 19:39 last edited by
              #6

              @stilgar Hi; I am on the same situation. Did you solve ?

              1 Reply Last reply
              0

              • Login

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