[python] does durable_rules swallow exceptions?
Having the
There's this mockup with and without try/except block there are the same two distinct errors in each:
- ZeroDivisionError
- TypeError
with ruleset('swallow_error'):
@when_all(
(m.foo == True) &
(m.bar != None)
)
def catch_do(c):
bar_val = str(c.m.bar)
ugly = 10/0
# c.s.ret = {}
c.s.ret.update({1: {'path': f'{c.m.foo}', 'value': bar_val}})
with ruleset('expose_error'):
@when_all(
(m.foo == True) &
(m.bar != None)
)
def catch_do(c):
try:
bar_val = str(c.m.bar)
ugly = 10 / 0
# c.s.ret = {}
c.s.ret.update({1: {'path': f'{c.m.foo}', 'value': bar_val}})
except Exception as e:
print(f"{type(e).__name__}: {e.args[0]}, {e.args[1:]}")
jj = {'foo': True, 'bar': 'Lorem ipsum'}
Calling post() on each ruleset
answ1 = post('swallow_error', jj)
answ2 = post('expose_error', jj)
will return:
ZeroDivisionError: division by zero, ()
Process finished with exit code 0
Also executing with
answ1 = post('swallow_error', jj)
print(f"answ1.ret: {answ1['ret']}")
answ2 = post('expose_error', jj)
Returns
Traceback (most recent call last):
File "/.../durarules.py", line 1237, in <module>
print(f"answ1.ret: {answ1['ret']}")
KeyError: 'ret'
Process finished with exit code 1
Which is thrown after durable_rules finished running.
In my actual code nested try/except block revealed multiple TypeError exceptions (eg. trying to use dict.update() as c.s.var.update({...})) of which durable rules happily ignored, causing some head-scratching.
Hi, thanks for asking the question. The action execution is not guaranteed to be synchronous with event Post or Fact assert/retract. Exceptions are caught and set in the context state.
with ruleset('flow1'):
@when_all(m.action == 'start')
def first(c):
raise Exception('Unhandled Exception!')
# when the exception property exists
@when_all(+s.exception)
def second(c):
print('flow1-> expected {0}'.format(c.s.exception))
c.s.exception = None
post('flow1', { 'action': 'start' })
Thank you!
That explains it. So I have two options, either wrap each consequent function-body in a try/except block or rely on the c.s.exception value.
These give plenty of freedom. Ta