fix(system): stop native_python impl swallowing errors into None

@logger.catch defaults to reraise=False, so change_password and
get_debug_logs_raw - which raise NotImplementedError - silently
returned None. The service layer's 'except NotImplementedError -> 501'
never fired, yielding '200 null' or a response-model 500 instead.
login likewise turned unexpected errors into a None result.

Drop the pointless decorator from the two methods that only raise, and
let login reraise so failures surface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
fusion44 2026-07-03 21:44:25 +02:00
parent c4afca50e9
commit cf423f52c1
No known key found for this signature in database
2 changed files with 39 additions and 3 deletions

View file

@ -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()

View file

@ -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"))