Skip to content

Custom Constraint Handling

Val Huber edited this page Apr 14, 2023 · 8 revisions

Background

Default Contraint Exception Handling

By default, Logic Bank raises ConstraintExceptions when constraints are violated. You can handle them as shown in examples/nw/tests/test_add_order.py:

try:
    session.commit()
except ConstraintException as ce:
    print("Expected constraint: " + str(ce))
    session.rollback()
    did_fail_as_expected = True
except:
    self.fail("Unexpected Exception Type")

if not did_fail_as_expected:
    self.fail("huge order expected to fail, but succeeded")
else:
    print("\n" + prt("huge order failed credit check as expected.  Now trying non-commissioned order, should also fail..."))

How to Address Custom Constraint Requirements?

Some containers (e.g., Flask) expect constraints to derive from a specific class. Logic Bank provides support for custom exception handling, as described below.

Custom Constraint Handler

See examples/custom_exceptions/tests/run_custom_constraints (Note the 3rd argument to activate, below):

class MyConstraintException(ConstraintException):
    pass

def constraint_handler(message: str, constraint: Constraint, logic_row: LogicRow):
    error_attrs = ""
    if constraint:
        if constraint.error_attributes:
            for each_error_attribute in constraint.error_attributes:
                error_attrs = error_attrs + each_error_attribute.name + " "
    exception_message = "Custom constraint_handler for: " + message +\
                        ", error_attributes: " + error_attrs
    logic_row.log(exception_message)
    raise MyConstraintException(exception_message)


from examples.custom_exceptions.logic.rules_bank import declare_logic
LogicBank.activate(session=session, activator=declare_logic, constraint_event=constraint_handler)

You can handle such constraints like this:

did_fail_as_expected = False
session.add(new_order)
try:
    session.commit()
except MyConstraintException as ce:
    print("\nExpected constraint: " + str(ce))
    session.rollback()
    did_fail_as_expected = True
except:
    assert False, "Unexpected Exception Type"