aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Goldstein <max.goldstein@qt.io>2021-03-01 15:34:58 +0100
committerMaximilian Goldstein <max.goldstein@qt.io>2021-03-04 08:59:53 +0100
commit890cb4cb236333fd5b112fffc0e9088ecb43f2df (patch)
tree99f86373be14f2398b8917a4b264f4033a774fb5
parentd8c9becf9ca807f27d44475bcdab75b7a71681ff (diff)
qqmlapplicationengine: Handle errors during component creation
Previously QQmlApplicationEngine did not handle any errors that occurred during object creation (i.e. failures to initialize required properties) which lead to QObject::connect errors and to the error messages not getting printed among other issues. Pick-to: 5.15 6.0 6.1 Change-Id: I69bc566a6d349c786cae82a963a621388684c8f5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp8
-rw-r--r--tests/auto/qml/qqmlapplicationengine/data/Required.qml6
-rw-r--r--tests/auto/qml/qqmlapplicationengine/data/requiredViolation.qml3
-rw-r--r--tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp18
4 files changed, 35 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index d866301f84..e0ab25892f 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -152,6 +152,14 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
break;
case QQmlComponent::Ready: {
auto newObj = initialProperties.empty() ? c->create() : c->createWithInitialProperties(initialProperties);
+
+ if (c->isError()) {
+ qWarning() << "QQmlApplicationEngine failed to create component";
+ warning(c->errors());
+ q->objectCreated(nullptr, c->url());
+ break;
+ }
+
objects << newObj;
QObject::connect(newObj, &QObject::destroyed, q, [&](QObject *obj) { objects.removeAll(obj); });
q->objectCreated(objects.constLast(), c->url());
diff --git a/tests/auto/qml/qqmlapplicationengine/data/Required.qml b/tests/auto/qml/qqmlapplicationengine/data/Required.qml
new file mode 100644
index 0000000000..dd45902bef
--- /dev/null
+++ b/tests/auto/qml/qqmlapplicationengine/data/Required.qml
@@ -0,0 +1,6 @@
+import QtQml
+
+QtObject
+{
+ required property int foo
+}
diff --git a/tests/auto/qml/qqmlapplicationengine/data/requiredViolation.qml b/tests/auto/qml/qqmlapplicationengine/data/requiredViolation.qml
new file mode 100644
index 0000000000..21c29ca6c2
--- /dev/null
+++ b/tests/auto/qml/qqmlapplicationengine/data/requiredViolation.qml
@@ -0,0 +1,3 @@
+import QtQml
+
+Required {}
diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
index 365e40dfeb..a35375d6f3 100644
--- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
+++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
@@ -56,6 +56,7 @@ private slots:
void translationChange();
void setInitialProperties();
void failureToLoadTriggersWarningSignal();
+ void errorWhileCreating();
private:
QString buildDir;
@@ -333,6 +334,23 @@ void tst_qqmlapplicationengine::failureToLoadTriggersWarningSignal()
QTRY_COMPARE(warningObserver.count(), 1);
}
+void tst_qqmlapplicationengine::errorWhileCreating()
+{
+ auto url = testFileUrl("requiredViolation.qml");
+ QQmlApplicationEngine test;
+ QSignalSpy observer(&test, &QQmlApplicationEngine::objectCreated);
+
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QQmlApplicationEngine failed to create component");
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, qPrintable(QStringLiteral("%1:5:5: Required property foo was not initialized").arg(testFileUrl("Required.qml").toString())));
+
+ test.load(url);
+
+ QTRY_COMPARE(observer.count(), 1);
+ QList<QVariant> args = observer.takeFirst();
+ QVERIFY(args.at(0).isNull());
+ QCOMPARE(args.at(1).toUrl(), url);
+}
+
QTEST_MAIN(tst_qqmlapplicationengine)
#include "tst_qqmlapplicationengine.moc"