QMLJS: Fix exception handling in promises

If an exception is thrown inside a promise's resolve or reject
handler, the promise needs to resolve into a rejected state with the
exceptions value. The value was previously not set.

Fixes: QTBUG-78554
Change-Id: Ic22faa6ef1e519e4cae6732c69bb14f7053d13da
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Fabian Kosmale 2019-09-20 16:38:30 +02:00
parent 5e96f43fe0
commit 36be27265d
3 changed files with 30 additions and 0 deletions

View File

@ -163,6 +163,7 @@ void ReactionHandler::executeReaction(ReactionEvent *event)
ScopedFunctionObject reaction(scope);
if (scope.hasException()) {
reaction = capability->d()->reject.as<QV4::FunctionObject>();
result = scope.engine->catchException();
} else {
reaction = capability->d()->resolve.as<QV4::FunctionObject>();
}

View File

@ -0,0 +1,17 @@
import QtQuick 2.12
Item {
id: root
property string errorMessage
Component.onCompleted: () => {
let prom = Promise.reject("Some error")
.then(
o => {console.log("Never reached");},
err => {
console.log("Rethrowing err");
throw err;
}
)
.catch(err => root.errorMessage = err)
}
}

View File

@ -83,6 +83,7 @@ private slots:
void then_reject_non_callable();
void then_resolve_multiple_then();
void promiseChain();
void promiseHandlerThrows();
private:
void execute_test(QString testName);
@ -285,6 +286,17 @@ void tst_qqmlpromise::promiseChain()
}
void tst_qqmlpromise::promiseHandlerThrows()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("promisehandlerthrows.qml"));
QVERIFY(component.isReady());
QTest::ignoreMessage(QtDebugMsg, "Rethrowing err");
QScopedPointer<QObject> root(component.create());
QVERIFY(root);
QTRY_VERIFY(root->property("errorMessage") == QLatin1String("Some error"));
}
QTEST_MAIN(tst_qqmlpromise)