Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-89719

Improve QML's error handling

    XMLWordPrintable

Details

    Description

      Hello!

      Summary:

      1. Add interception API point to QML engine which is invoked when engine performs call from QML/JS to native code
      2. Allow creation of user-defined JS exception types from native code and/or addition of custom info to exception instances
      3. Add distinct type instead of QQmlError to report exceptions through QQmlEngine's signal. That type should keep as much exception information as possible, including unmodified message, stack trace and additional info.

      Rationale:
      GUI applications are usually complex, much more complex than CLI ones. And while strategy "terminate on any unexpected errors" is Ok for small CLI utility, it's usually not acceptable for large GUI product. Some errors come unexpected during product development, and most of them should be intercepted and logged, and app should be allowed to continue. Here's where QML's exception-unfriendliness comes into play. According to what I've read in docs and to answers on forum, one is required to return some error value in case of failure and propagate it manually upwards the stack. Such approach both produces boilerplate and is error-prone itself. Not to mention it requires special code tuning and works only with Q_INVOKABLE methods which can return something. Exceptions could be used as uniform solution to the issue, by first transforming C++ ones to JS ones, thus unifying exception flow, and them catching them at the bottom of stack and doing something useful to them like reporting. More importantly, this can be opt-in from app developers, with local modifications to Qt sources and no need to support C++ exceptions explicitly.

      Details:
      I'm now participating in development of QML-based desktop application. And we use exceptions as a way to report errors. What came to my eye is that QML engine is unfortunately very exception-unfriendly both in native and interpreted part, unlike Qt Widgets.

      First of all, stack unwinding through QML engine code causes unavoidable program state corruption, to the point of unrelated random crash at random location. This could have been mitigated if we had overridable virtual method in QJSEngine or QQmlEngine similar to QCoreApplication::notify, in which case application developers could override that method, add catch-block and transform C++ exception to JS one. Unfortunately we don't have one.

      Second, QQmlEngine::warnings signal is fired on any message-like event, mixing actual JS exceptions with service messages. It would be really nice to have signal specifically for that case. QQmlError, as noted even in source comments, is more like log message than actual error.

      Third, QJSEngine allows to spawn only fixed set of error types. This prevents transfer of additional information in exception context. I had to pack JSON into description to pass that information.

      Fourth, QQmlError itself isn't the best type for representing exceptions. It keeps only single frame of stacktrace, loses all possible additional information and exception type, and warps error message by adding JS-specific things like actual error type name to description string. Would be nice to have some kind of string-value map or JSON object.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            igor-baidiuk I B
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes