enhancement
major
minor
defect
critical
major
minor
minor
#30265
TL Script: When `throw()` is used or a `TopLogicException` occurs, `try()` passes only the message text to the `catch` block instead of the `ResKey`.
Background
A view should handle an error that occurs while reading content and display the message itself, rather than causing the selection to fail. Example: The preview of a document whose content is stored in an unconnected third-party system.
Problem
According to the documentation, the catch function of try($eval, $catch) receives “the ResKey for an I18NException, otherwise the error text.” To do this, `try.internalEval ` checks if the exception is an `I18NException`. However, the errors commonly encountered in TL-Script are ` I18NRuntimeExceptions`:
- throw(#"my.key") (runtime error with ResKey)
- TopLogicException from Java functions
For these, the `catch` block only receives `e.getMessage()`, i.e., the text in the server’s language (English in this case), not the ResKey. A German-language interface then displays the message in English. The message for the command itself (error dialog or hint), however, is translated correctly.
Version: 8.0.0-alpha12 (com.top_logic.model.search.expr.Try).
Reproduction
- Evaluate the following in a German-language session: ` try(throw(#"tl.some.key"), catch: m -> v -> $m) ` with a key that has a German translation.
- Result: a string containing the English text (or the key), no ResKey.
Expected behavior
For every exception with an error key (I18NException and I18NRuntimeException), the catch block receives the ResKey.
Workaround
The preview displays a generic message (“The content of this version cannot be read …”) and logs the reason as a WARN; the exact reason is reported upon download.
Solution
The `try()` block passes the error message to the `catch` block as a `ResKey ` (the `try` block checks for `I18NFailure`, the common interface of `I18NException ` and `I18NRuntimeException`). The message is thus displayed in the interface language. This applies to
- the error from ` throw()`, even if ` throw() ` was passed plain text (in which case a literal ResKey with that text is used),
- errors from functions: a TopLogicException provides its own key; every other Java exception is reported by the evaluation with the key “Evaluation of ... failed” anyway.
Fixed in this release:
- The key “Evaluation of ... failed” (SearchExpression.evalWith) contained the live evaluation context. If the catch function binds the message to a variable in this context, the key contained itself; any text representation (localize(), toString(), log()) resulted in a StackOverflowError. The key now contains the variable assignment at the time of the error as text.
- log(message, args...) inserted a ResKey as an argument into the message using its internal encoding. It is now inserted as translated text, e.g., in catch: e -> log("... Reason: {0}", $e).
The help page for the try function describes this behavior.
Migration
The catch function of try() always receives the error message as a ResKey, no longer as a string. No adjustment is necessary for display or in log(). A script that processes the message as a string (length, regular expression, comparison with a string, concatenation) must first convert it using `localize()`:
try(..., catch: msg -> $msg.localize().contains("..."))
Test
- test.com.top_logic.model.search.expr.TestTryCatch
- test.com.top_logic.model.search.expr.TestLog