diff --git a/src/ape/utils/basemodel.py b/src/ape/utils/basemodel.py index 31f8b68837..3ca5c7bf8e 100644 --- a/src/ape/utils/basemodel.py +++ b/src/ape/utils/basemodel.py @@ -108,10 +108,12 @@ def only_raise_attribute_error(fn: Callable) -> Any: def wrapper(*args, **kwargs): try: return fn(*args, **kwargs) - except Exception as e: + except AttributeError: + raise # Don't modify or log attr errors. + except Exception as err: # Wrap the exception in AttributeError logger.log_debug_stack_trace() - raise ApeAttributeError(f"{e}") from e + raise ApeAttributeError(f"{err}") from err return wrapper diff --git a/tests/functional/utils/test_basemodel.py b/tests/functional/utils/test_basemodel.py index 79c3d8909c..105c9d76ba 100644 --- a/tests/functional/utils/test_basemodel.py +++ b/tests/functional/utils/test_basemodel.py @@ -1,7 +1,8 @@ import pytest from ape.exceptions import ProviderNotConnectedError -from ape.utils.basemodel import ManagerAccessMixin +from ape.logging import logger +from ape.utils.basemodel import ManagerAccessMixin, only_raise_attribute_error class CustomClass(ManagerAccessMixin): @@ -22,3 +23,30 @@ def test_provider_not_active(networks, accessor): _ = accessor.provider finally: networks.active_provider = initial + + +def test_only_raise_attribute_error(mocker, ape_caplog): + spy = mocker.spy(logger, "log_debug_stack_trace") + + @only_raise_attribute_error + def fn(): + raise ValueError("foo bar error") + + with pytest.raises(AttributeError, match="foo bar error"): + fn() + + assert spy.call_count + + +def test_only_raise_attribute_error_when_already_raises(mocker, ape_caplog): + spy = mocker.spy(logger, "log_debug_stack_trace") + + @only_raise_attribute_error + def fn(): + raise AttributeError("foo bar error") + + with pytest.raises(AttributeError, match="foo bar error"): + fn() + + # Does not log because is already an attr err + assert not spy.call_count