(core) Adding traceback to trigger formulas

Summary:
Traceback is available on the Creator Panel in the formula editor. It is evaluated the same way as for normal formulas.
In case when the traceback is not available, only the error name is displayed with information that traceback is not available.
Cell with an error, when edited, shows the previous valid value that was used before the error happened (or None for new rows).
Value is stored inside the RaisedException object that is stored in a cell.

Test Plan: Created tests

Reviewers: alexmojaki

Reviewed By: alexmojaki

Subscribers: alexmojaki, dsagal

Differential Revision: https://phab.getgrist.com/D3033
This commit is contained in:
Jarosław Sadziński
2021-09-25 21:14:19 +02:00
parent 048c8ee165
commit 8684c9e930
11 changed files with 244 additions and 52 deletions

View File

@@ -138,7 +138,7 @@ class BaseColumn(object):
"""
self.set(row_id, self.getdefault())
def get_cell_value(self, row_id):
def get_cell_value(self, row_id, restore=False):
"""
Returns the "rich" value for the given row_id, i.e. the value that would be seen by formulas.
E.g. for ReferenceColumns it'll be the referred-to Record object. For cells containing
@@ -146,8 +146,13 @@ class BaseColumn(object):
error, this will re-raise that error.
"""
raw = self.raw_get(row_id)
if isinstance(raw, objtypes.RaisedException):
if isinstance(raw.error, depend.CircularRefError):
# For trigger formulas, we want to restore the previous value to recalculate
# the cell one more time.
if restore and raw.has_user_input():
raw = raw.user_input
elif isinstance(raw.error, depend.CircularRefError):
# Wrapping a CircularRefError in a CellError is often redundant, but
# TODO a CellError is still useful if the calling cell is not involved in the cycle
raise raw.error