enhancement
major
minor
defect
critical
major
minor
major
#30201
Commit veto of the model constraints: a failed job (and its log) shows only "Cannot store, constraints violated." without the problems
Problem
ModelService.checkCommit refuses a commit with I18NConstants.CONSTRAINTS_VIOLATED ("Speichern nicht möglich. Wertüberprüfung fehlgeschlagen.") and hangs the problems it found (at most ten) on it as the exception's cause chain. A job of the view layer (com.top_logic.layout.view.job) that fails with this exception shows only the top message to the user, and nothing is logged at ERROR. The user learns neither which object nor which constraint refused.
Seen in E-Home (8.0.0-alpha12.817): an ETS project import, run as a job, ends with "Speichern nicht möglich, Wertüberprüfung fehlgeschlagen" and nothing else; the server log holds only the INFO lines of the import.
Reproduction
- A job whose run commits a transaction that violates any model constraint (e.g. a <constraint-by-expression> that always refuses).
- Start the job from a view; the failure dialog shows only "Cannot store, constraints violated."; the log has no entry with the problems.
Expected
The message of the veto names the problems (e.g. the texts of the causes, joined), or the job's failure display shows the cause chain of an I18NRuntimeException; the job failure is logged with its stack trace.
Workaround in E-Home
The import catches the veto at its commit, reads the causes and fails with a message of its own that names them, and logs it at ERROR.
Solution
- A failed job keeps the whole message of its failure: JobRunner describes a failure carrying a message for the user (anywhere in its cause chain) the way a failed command does (CommandErrors.messages) - the first internationalized message as the error, its details and the messages of the internationalized causes below it (for a vetoed commit: the individual constraint violations) as the error details of the job state (JobState.errorDetails()). Any other failure still ends the job with the generic "The operation failed: ..." message.
- The job status display (<job-status>, TLJobStatus) lists the error details below the error inside its alert, styled like the list in the snackbar of a failed command (CSS element tl-job-status__details).
- The TL-Script function jobErrorDetails(job) gives the error details of a job, next to jobError(job).
- A job that fails with a user-level (internationalized) failure is logged at WARN with its stack trace and all its messages; an internal error stays logged at ERROR. A job runs in the background, so its window may be gone when it fails.
- The problems of a constraint veto are chained in the order they were found; before, a reader of the cause chain (also the snackbar of a failed command) listed them in reverse order.
- Demo (tl-demo-react, Demos → Long-running job): the button "Store an invalid object" starts a job whose commit the model constraints veto; the display lists the two violated constraints.