diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2021-03-01 15:34:58 +0100 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2021-04-14 16:47:16 +0200 |
commit | e1163220c71a6dfc326534f65ebeeade972f857c (patch) | |
tree | 19b8c483ee52c00c02a38091641f0e3c18d2c0d8 | |
parent | c7c2512a6736ff9fff7d3ed1b90fb6d57a656bcb (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.
Change-Id: I69bc566a6d349c786cae82a963a621388684c8f5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 890cb4cb236333fd5b112fffc0e9088ecb43f2df)
4 files changed, 35 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 9af3437cb0..8f7f2e48eb 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -146,6 +146,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..acf4a00ce6 --- /dev/null +++ b/tests/auto/qml/qqmlapplicationengine/data/Required.qml @@ -0,0 +1,6 @@ +import QtQml 2.15 + +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..c5de4661a9 --- /dev/null +++ b/tests/auto/qml/qqmlapplicationengine/data/requiredViolation.qml @@ -0,0 +1,3 @@ +import QtQml 2.15 + +Required {} diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp index f636e527c3..4306c7b8ca 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" |