diff --git a/app/system/impl/native_python.py b/app/system/impl/native_python.py index 5dfdb6f..031a681 100644 --- a/app/system/impl/native_python.py +++ b/app/system/impl/native_python.py @@ -69,7 +69,7 @@ class NativePythonSystem(SystemBase): # return an empty connection info object for now return Ok(ConnectionInfo()) - @logger.catch(exclude=(HTTPException,)) + @logger.catch(exclude=(HTTPException,), reraise=True) async def login(self, i: LoginInput) -> Result[Dict[str, str], Report]: # https://github.com/fusion44/blitz_api/issues/255 pw = config("BAPI_NATIVE_LOGIN_PASSWORD", cast=str) @@ -108,11 +108,11 @@ class NativePythonSystem(SystemBase): ) ) - @logger.catch(exclude=(HTTPException,)) async def change_password(self, type: str, old_password: str, new_password: str): + # no @logger.catch: NotImplementedError must propagate to the service + # layer (which turns it into a 501), not be swallowed into a None return raise NotImplementedError() - @logger.catch(exclude=(HTTPException,)) async def get_debug_logs_raw(self) -> RawDebugLogData: raise NotImplementedError() diff --git a/tests/test_native_python_errors.py b/tests/test_native_python_errors.py new file mode 100644 index 0000000..707cad1 --- /dev/null +++ b/tests/test_native_python_errors.py @@ -0,0 +1,36 @@ +""" +Regression tests: the native_python system impl must not swallow exceptions. + +@logger.catch defaults to reraise=False, so methods that raise +NotImplementedError silently returned None. The service layer relies on +NotImplementedError propagating (to return 501) and on unexpected errors +surfacing rather than becoming a None result. +""" + +import pytest + +from app.system.impl import native_python as np + + +def _system(): + return np.NativePythonSystem() + + +async def test_change_password_raises_not_implemented(): + with pytest.raises(NotImplementedError): + await _system().change_password("a", "old", "new") + + +async def test_get_debug_logs_raw_raises_not_implemented(): + with pytest.raises(NotImplementedError): + await _system().get_debug_logs_raw() + + +async def test_login_does_not_swallow_unexpected_errors(monkeypatch): + def boom(*args, **kwargs): + raise RuntimeError("config exploded") + + monkeypatch.setattr(np, "config", boom) + + with pytest.raises(RuntimeError): + await _system().login(np.LoginInput(password="12345678"))