Global exception handling with c++/QML
-
wrote on 18 Aug 2017, 13:07 last edited by
Hello. My task is to create an unhandled exception catching mechanism in an application with Qml UI and heavy c++ business logic. I am registering
types using qmlRegisterType<> and create instances in Qml layer;MyApplication app(argc, argv); QQmlApplicationEngine *engine = new QQmlApplicationEngine(); qmlRegisterType<presentation::uimodels::LoginForm>("Models", 0, 1, "LoginFormModel"); engine->load(QUrl("qrc:/qml/views/LoginForm.qml")); return app.exec();
Item { Component.onCompleted: { model.login(); } LoginFormModel { id: model } }
I have a global exception handler, catching std::exceptions in overriden QGuiApplication::notify function and also a POSIX signal handler, in case that something bad like access violation errors happened.
The problem is that unhandled exceptions thrown in my login() function did not get caught anywhere. Application just crashes unexpectedly without doing any post-exception handling. Is there a proper way of handling c++ exceptions with Qml or am i doing something wrong here. Please need advise. -
wrote on 18 Aug 2017, 14:43 last edited by
Your C++ class should handle all exceptions. The invokable methods may return Status or have a Status member like QQmlComponent. So, you should check for those values in order to detect any error.
-
wrote on 19 Aug 2017, 10:35 last edited by
Yes, what @stevemcgf said. C++ exceptions are basically just another C++ flow-control construct but don't have a lot of meaning outside of the C++ domain. You might as well expect to be able to
goto
some QML from C++. And Qt has a long enough history it predates the fashion to use exceptions as a core error handling mechanism (like you find in the Java and C# worlds); http://doc.qt.io/qt-5/exceptionsafety.html is worth a read.(Brings back memories of years ago having to wrap exception-happy C++ as Microsoft COM componentry (where the standard was to use HRESULT return codes for all error handling). There was just no good alternative but to
try { } catch (std::exception& e)
in every method exposed to COM. Actually it was worse than that because some code was throwing types not derived from std::exception, but that's another story.) -
wrote on 22 Aug 2017, 08:21 last edited by
Thank you for your replies. Unfortunately by handling everything manually and fully rely on it means that we can give up on top-level handlers completely because there is not much point in them that way. That approach feels dangerous and unreliable, we would still like to have some mechanism on client side that would at least gather some logs and send them to us in case that something went terribly wrong.
P.S. By reading forums and experimenting a bit i have found out that throwing exceptions through Qml layer is still possible in debug mode with Qml debugger on, so i will try to dig in this direction. -
wrote on 24 Aug 2017, 07:06 last edited by
Update. I have found a hacky solution to my problem. Surprisingly, wrapping my model.login() call in try/catch block does the magic. Exceptions start to propagate through Qml and get caught in global handlers. This solution is still far from optimal, that's definetely not a good design to write multiple try/catches in UI layer. Also, try/catch mechanism is quite buggy in the moment. Still looking for a better solution.
1/5