wmayer wrote:I would prefer a special Exception class. Not sure if we need a whole set of classes for this or if one is sufficient.
I was not referring to a full duplication. I was referring to some duplication. But I see your point.wmayer wrote: As said above we don't need a translated and an untranslated version for each exception type. When you have a look at Exception.h then most of them are used to describe some pure technical problems. The only type which may also show informative text to the user is RuntimeError. So, for me it's fine to have only one exception class used for translation.
The rest of this message is product of a brainstorming and I post it not to forget about it. Feel free to stop reading here.
The first question to answer is: Do we need to differentiate between different types of exceptions that offer or should offer a translatable text?
As particular examples of today I can think of:
1) OCC exception that is catch and thrown as a base exception, for example CADKernelError exception. In this case the translatable message is fixed and exception class defined "CAD kernel error".
2) A value error exception (I have been using the ValueError, e.g. "BSpline GeoId is out of bounds." but I can agree to any other name, it is generally just something the user entered wrongly, or an error in the UI command code). The translatable message is given by the user via the macro, though I have not tested it, probably the macro could pass the string thru QT_TRANSLATE_NOOP using a context like QObject (or any other), so that lupdate marks the text for translation. NOTE: We do not want to provide the translation itself when throwing, to be able to use the original English message for the report view.
As a general principle, the mechanism should serve the two purposes (allow for specialized catching, i.e. the reason why we do not use Base::Exception everywhere, and reducing the UI message generation), the mechanism should allow that any exception susceptible of generating a developer (exception class user) defined text message can be used as translatable (it does not necessarily need to know it is translatable, see below). A general workflow:
1. The developer has a function where different types of exceptions are thrown.
2. The developer has a good message for the UI on several of them (not necessarily all).
3. The developer uses the different types, so that at the moment of catching (elsewhere), he can differentiate between types.
4. At the moment of catching (elsewhere), appropriate action is taken for each type and the exception (the same or a specialized one) is rethrown for the UI.
One solution is to use two different macros for the initial throwing. One for when the message is translatable (Macro1), another for when it is not (Macro2). There are several possible implementations. One would be that Macro1 passes the text thru QT_TRANSLATE_NOOP and macro2 does not. In this implementation (4) can not know whether the text is translatable or not, but it could by default rethrow the exception for the UI. The UI has access to the translation engine, so it should be possible to detect whether the message was marked for translation or not (it was thrown via Macro1 or Macro2). If at runtime the message can not be found in the translation engine, then a default error is shown. If it can be found, the translation is shown.
Maybe this could work without any specific exception. I will try it and come back.