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
QtWS25 Last Chance

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 pablo_worker
    #1

    Hi!,

    Does anyone know how to create a QJSValue of type Error?

    Context: I use QJSEngine::evaluate() to execute JavaScript code, that JavaScript code calls a C++ function. The QJSEngine::evaluate() throws a script exception (QJSValue of type Error) only if there is an error in the JavaScript code. Therefore, if there is an error in the C++ function I want to return a QJSValue of type error. I am following that path becasue QJSEngine::evaluate does not catch C++ exceptions.

    Thank you so much.

    1 Reply Last reply
    0
    • 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