[SOLVED] Reporting Javascript errors to users

  • Dear all,
    I'm playing with QML trying to use it in a non-GUI program. It works very well :-)
    But now, I would to report javascript errors to the users and I did not find a way to do it.

    This is the way I'm using QML.
    The user write a qml script that contains a root element defined by me with some javascript function inside, that's an example:
    Experiment {
    function initGeneration( id ) {
    world.addSphere( "target", 0.02 );
    target.setMass( 0.0 );
    target.setMaterial( "targetMaterial" );
    target.setMatrix( utils.identityMatrix() );
    logger.info( "PureReachAbs - Main Initialization done" );
    In the example above, "world", "target", "utils" and "logger" are all global object defined by C++ application using QDeclarativeContext::setContextProperty().

    I create the Experiment instance from the C++ application using the QDeclarativeComponet::create() method.
    If there is an syntax error in the QML script the create method reports it correctly ... but it cannot check if the global variables exist or not.
    So, supposing to change the following line:
    logger.info( "PureReachAbs - Main Initialization done" );

    with a one with a "logger" written wrongly:

    loggre.info( "PureReachAbs - Main Initialization done" );

    The QDeclarativeContext::create() do not report any syntax error. And that's fine.

    But when later, I use from C++ application the QMetaObject::invokeMethod in order to call the javascript function "initGeneration" with the wrong line, what it happens is that it is not executed and no errors is reported back.
    So, I cannot display to the user a error saying something like: "loggre is undefined".

    How can I do that ?? There is a way to report these errors to the user ??

    Thank you,

  • I'm too lazy to understand it all but maybe wrapping code in try-catch (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/try...catch) will help?

    E.g. node output here:

    @> fldksf
    ReferenceError: fldksf is not defined
    at repl:1:2
    at REPLServer.eval (repl.js:80:21)
    at Interface.<anonymous> (repl.js:182:12)
    at Interface.emit (events.js:67:17)
    at Interface._onLine (readline.js:162:10)
    at Interface._line (readline.js:426:8)
    at Interface._ttyWrite (readline.js:603:14)
    at ReadStream.<anonymous> (readline.js:82:12)
    at ReadStream.emit (events.js:88:20)
    at ReadStream._emitKey (tty.js:327:10)

    try { flskdjf } catch (e) { console.log(e); }
    [ReferenceError: flskdjf is not defined]@

  • Thank you.
    You give me a possible solution. Now, I only need a way to propagate the Javascript exceptions to C++ application.
    If it is possible to propagate any exception raised by a QML script to the C++ application, then I resolved my problem.
    Anyone know how to do it ?


  • Maybe you could pass some object to QML using setContextProperty (e.g. QString) and set value to it on exception. I'm not sure if that will work but you could try.

  • I found the solution !!
    Thank you for the hint given to me :-)

    The solution is to use QDeclarativeExpression instead of QMetaObject::invokeMethod.
    Here are the details:
    suppose you have the following QML component
    Experiment {
    function initGeneration( id ) {
    // some javascript code here

    Then you can call the function from C++ using the invokeMethod:
    QMetaObject::invokeMethod( qe_experiment, "initGeneration", Qt::DirectConnection, Q_ARG(QVariant, generation) );

    But in this way, if there is a javascript error or exception evaluating the function there will be no way to report a message to the user.
    Instead, it is possible to call the function using a QDeclerativeExpression in this way:
    qe_expr->setExpressio( QString("initGeneration(%1);").arg(generation) );
    if ( qe_expr->hasError() ) {
    qDebug() << qe_expr->error();

    And in this way, it will be prompted an error message specifying the error and the line number.

    Thank you very much,

Log in to reply