diff options
3 files changed, 51 insertions, 0 deletions
diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp index 40ad93a544..098894aeb0 100644 --- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp +++ b/src/declarative/qml/v8/qv8qobjectwrapper.cpp @@ -51,6 +51,7 @@ #include <private/qjsvalue_p.h> #include <private/qscript_impl_p.h> #include <private/qdeclarativeaccessors_p.h> +#include <private/qdeclarativeexpression_p.h> #include <QtDeclarative/qjsvalue.h> #include <QtCore/qvarlengtharray.h> @@ -1229,11 +1230,22 @@ int QV8QObjectConnectionList::qt_metacall(QMetaObject::Call method, int index, v Connection &connection = connections[ii]; if (connection.needsDestroy) continue; + + v8::TryCatch try_catch; if (connection.thisObject.IsEmpty()) { connection.function->Call(engine->global(), argCount, args.data()); } else { connection.function->Call(connection.thisObject, argCount, args.data()); } + + if (try_catch.HasCaught()) { + QDeclarativeError error; + error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(engine->toString(connection.function->GetName()))); + v8::Local<v8::Message> message = try_catch.Message(); + if (!message.IsEmpty()) + QDeclarativeExpressionPrivate::exceptionToError(message, error); + QDeclarativeEnginePrivate::get(engine->engine())->warning(error); + } } connectionList.connectionsInUse--; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qobjectConnectionListExceptionHandling.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qobjectConnectionListExceptionHandling.qml new file mode 100644 index 0000000000..acd512a2be --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qobjectConnectionListExceptionHandling.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Item { + id: root + property int first: 5 + property bool test: false + + Item { + id: exceptional + function exceptionalFunction() { + var obj = undefined; + var prop = undefined; + return obj[prop]; + } + } + + Component.onCompleted: { + root["firstChanged"].connect(exceptional.exceptionalFunction); + root["firstChanged"].connect(exceptional.exceptionalFunction); + root["firstChanged"].connect(exceptional.exceptionalFunction); + first = 6; + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 0e3cfd8970..05e14cfc94 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -199,6 +199,7 @@ private slots: void qtbug_11606(); void qtbug_11600(); void qtbug_21864(); + void qobjectConnectionListExceptionHandling(); void nonscriptable(); void deleteLater(); void in(); @@ -5181,6 +5182,20 @@ void tst_qdeclarativeecmascript::qtbug_21864() delete o; } +void tst_qdeclarativeecmascript::qobjectConnectionListExceptionHandling() +{ + // QTBUG-23375 + QDeclarativeComponent component(&engine, testFileUrl("qobjectConnectionListExceptionHandling.qml")); + QString warning = component.url().toString() + QLatin1String(":13: TypeError: Cannot read property 'undefined' of undefined"); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + // Reading and writing non-scriptable properties should fail void tst_qdeclarativeecmascript::nonscriptable() { |