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. How to create a QJSValue object of type Error

How to create a QJSValue object of type Error

Scheduled Pinned Locked Moved Unsolved General and Desktop
qjsengineqjsvalue
11 Posts 2 Posters 4.5k Views
  • 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.
  • P Offline
    P Offline
    pablo_worker
    wrote on last edited by
    #2

    I add additional info:

    Here it is a code snippet of the intended functionality:

    void CMainWindow::slot_ExecuteJVScript()
    {
       myCppClass myObject(parameters); //It has a foo() method.
       QJSEngine myEngine;
       myEngine.globalObject().setProperty("myObj", myEngine.newQObject(&myObject)); //Now we can access the C++ object from JavaScript code.
       QString myScriptJS = "var X = myObj.foo()";  //Calling a C++ function from JavaScript
       QJSValue myValue = myEngine.evaluate(myScriptJS);
       if(myValue.isError())
       {
          //If there is an error in the JavaScript code we enter here
          //But I also wanto to enter here if there is an error in my foo() C++ function. 
       }
       else
       {
          //Do things with myValue
       }
    }
    

    Mini-Example of myCppClass::foo()

    QJSValue myCppClass::foo()
    {       
       if(something)
       {
           //Create a QJSValue myValue with some data
           return myValue;
       }
       else
       {   //ERROR
           //Create a QJSValue of type Error
           return myValueOfTypeError;
       }
    }
    
    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by p3c0
      #3

      @pablo_worker It seems that ErrorObject is under private headers so I doubt it could be used somehow.
      A dirty workaround would be to force an error from that function :)
      For eg. inside your else part.

      else
         {  
             QJSEngine engine;
             QJSValue val = engine.evaluate("f();"); //undefined function
             val.isError(); // this prints true
         }
      

      157

      P 1 Reply Last reply
      0
      • p3c0P p3c0

        @pablo_worker It seems that ErrorObject is under private headers so I doubt it could be used somehow.
        A dirty workaround would be to force an error from that function :)
        For eg. inside your else part.

        else
           {  
               QJSEngine engine;
               QJSValue val = engine.evaluate("f();"); //undefined function
               val.isError(); // this prints true
           }
        
        P Offline
        P Offline
        pablo_worker
        wrote on last edited by pablo_worker
        #4

        @p3c0 Thank you.
        However, the problem I see is now is that I can't return QJSValue. Because if it has been created inside a function it is deleted when the function ends.

        QJSValue myFunction() {
           QJSEngine engine;
           QJSValue val = engine.evaluate("asdf;"); //rubbish
           val.isError(); //this prints true
           return val;
        }
        
        QJSValue foo = myFunction();
        foo.isError(); //this prints false
        

        In addition, if it has been created with a QJSEngine, it loses its properties after the engine is deleted. Example:

        else
        {
             QJSValue val;
             {
                QJSEngine engine;
                val = engine.evaluate("f()");
                qDebug() << "val.isError:" << val.isError(); //this prints true
             }
             qDebug() << "val.isError:" << val.isError(); //this prints false
        }
        

        I could pass the QJSEngine instance to the function, but still, I don't know how to hard-copy the QJSValue.

        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #5

          @pablo_worker You can pass reference of the same QJSEngine.

          QJSValue myFunction(QJSEngine &engine) {
             QJSValue val = engine.evaluate("asdf;"); //rubbish
             val.isError(); //this prints true
             return val;
          }
          
          QJSEngine myEngine;
          myFunction(myEngine).isError();
          

          157

          P 1 Reply Last reply
          0
          • p3c0P p3c0

            @pablo_worker You can pass reference of the same QJSEngine.

            QJSValue myFunction(QJSEngine &engine) {
               QJSValue val = engine.evaluate("asdf;"); //rubbish
               val.isError(); //this prints true
               return val;
            }
            
            QJSEngine myEngine;
            myFunction(myEngine).isError();
            
            P Offline
            P Offline
            pablo_worker
            wrote on last edited by
            #6

            @p3c0 Yes, but the QJSValue is deleted after the "return" hence:

            myFunction(myEngine).isError();  //this returns false
            
            1 Reply Last reply
            0
            • p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #7

              @pablo_worker Nope. They are copied.

              157

              P 1 Reply Last reply
              0
              • p3c0P p3c0

                @pablo_worker Nope. They are copied.

                P Offline
                P Offline
                pablo_worker
                wrote on last edited by pablo_worker
                #8

                @p3c0
                I thought so, but there is something strange.
                In this case it is true:
                main.cpp

                #include <QCoreApplication>
                #include <QDebug>
                #include <QJSEngine>
                #include <QJSValue>
                
                QJSValue myFunction(QJSEngine &engine);
                
                int main(int argc, char *argv[])
                {
                   QCoreApplication a(argc, argv);
                   QJSEngine myEngine;
                   QJSValue theVal = myFunction(myEngine);
                   qDebug() << "theVal.isError():" << theVal.isError(); //this prints true
                   return a.exec();
                }
                
                QJSValue myFunction(QJSEngine &engine)
                {
                   QJSValue val = engine.evaluate("asf");
                   qDebug() << "val.isError():" << val.isError(); //this prints true
                   return val;
                }
                

                However, in this case it is not true

                Calling the cpp function from JavaScript.
                The debug output of this code is:

                In myFunction(), myVal.isError(): true
                Outside, theVal.isError(): false

                CMainWindow.h

                #include <QMainWindow>
                #include <QtWidgets>
                #include "myCppClass.h"
                
                class CMainWindow : public QMainWindow
                {
                   Q_OBJECT
                public:
                   CMainWindow(QWidget *parent = 0)
                   {
                      setCentralWidget(new QWidget(this));
                
                      QJSEngine myEngine;
                      myCppClass myObject(this, &myEngine); //this object has a myFunction() method.
                      myEngine.globalObject().setProperty("myObj" ,myEngine.newQObject(&myObject));
                      QJSValue theVal = myEngine.evaluate("var X = myObj.myFunction();"); //calling the function from Javascript
                      qDebug() << "Outside, theVal.isError():" << theVal.isError(); //this prints false
                   }
                };
                

                myCppClass.h

                #include <QObject>
                #include <QJSEngine>
                #include <QJSValue>
                #include <QDebug>
                
                class myCppClass : public QObject
                {
                   Q_OBJECT
                public:
                   explicit myCppClass(QObject *parent = 0, QJSEngine *theEngine = nullptr)
                      : QObject(parent), m_myEng(theEngine){}
                public slots:
                   QJSValue myFunction(){      
                      QJSValue myVal = m_myEng->evaluate("asdf"); //myVal will be a error.
                      qDebug() << "In myFunction(), myVal.isError():" << myVal.isError(); //this prints true;
                      return myVal;
                   }
                private:
                   QJSEngine *m_myEng;
                };
                

                main.cpp

                #include "CMainWindow.h"
                #include <QApplication>
                int main(int argc, char *argv[])
                {
                   QApplication a(argc, argv);
                   CMainWindow w;
                   w.show();
                   return a.exec();
                }
                
                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  pablo_worker
                  wrote on last edited by pablo_worker
                  #9

                  I have also noted something more, if I call the C++ function (that returns a QJSValue of type error) from JavaScript like this:

                  QJSValue theVal = myEngine.evaluate("var X = myObj.myFunction();"); //calling the c++ function from Javascript
                  

                  I don't get the error in the variable "theVal" [theVal.isError() will say "false"]

                  However, if I call the function like this:

                  QJSValue theVal = myEngine.evaluate("var X = myObj.myFunction(); X "); // note the X
                  

                  In this case the variable theVal does take the value X. And if I do theVal.isError() in this case it will show true.

                  Why is this?

                  1 Reply Last reply
                  0
                  • p3c0P Offline
                    p3c0P Offline
                    p3c0
                    Moderators
                    wrote on last edited by
                    #10

                    @pablo_worker So AFAICS something from JS should be returned so that evaluate reports proper output.

                    157

                    P 1 Reply Last reply
                    0
                    • p3c0P p3c0

                      @pablo_worker So AFAICS something from JS should be returned so that evaluate reports proper output.

                      P Offline
                      P Offline
                      pablo_worker
                      wrote on last edited by
                      #11

                      @p3c0 Thank you for your help.
                      The problem is that what I really want in the end is a way to catch errors thrown by C++ functions transparently to the user that writes JavaScript. So, the user can just write a script like:

                      var X = myCppFunction(foo);
                      var Y = myOtherCppFunction(bar);
                      etc.
                      

                      And when it is executed (myEngine.evaluate) the errors are catched by the C++ code of my application. Something like:

                      try
                      {
                          QJSValue theVal = myEngine.evaluate(the JavaScript script);
                          if(theVal.isError) {//if there are errors in the JS code enter here}
                      }
                      catch( )
                      {
                          // If there is an error in the Cpp functions called by the JS code enter here
                      }
                      

                      I have seen in this post that this is not currently possible with QJSEngine. In addition, I have seen that a ticket is already open. Therefore, I will have to think something to get around and wait untill the functionality is implemented.

                      Thank you for your help.

                      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