fix(tui-gateway): harden pending-title retry and user errors

Retry persisting queued titles on session.title reads and map title validation failures to a user-facing 4022 code instead of generic 5007.
This commit is contained in:
Brooklyn Nicholson
2026-04-27 11:27:51 -05:00
parent 492c4c6573
commit 3aa86717b6
2 changed files with 73 additions and 1 deletions

View File

@@ -375,6 +375,34 @@ def test_session_title_get_falls_back_to_pending_when_db_read_throws(monkeypatch
server._sessions.pop("sid", None)
def test_session_title_get_retries_persist_for_pending_title(monkeypatch):
class _FakeDB:
def __init__(self):
self.title = ""
def get_session_title(self, _key):
return self.title
def set_session_title(self, _key, title):
self.title = title
return True
def get_session(self, _key):
return {"id": _key, "title": self.title}
db = _FakeDB()
server._sessions["sid"] = _session(pending_title="queued title")
monkeypatch.setattr(server, "_get_db", lambda: db)
try:
resp = server.handle_request(
{"id": "1", "method": "session.title", "params": {"session_id": "sid"}}
)
assert resp["result"]["title"] == "queued title"
assert server._sessions["sid"]["pending_title"] is None
finally:
server._sessions.pop("sid", None)
def test_session_title_rejects_empty_title_with_specific_error_code(monkeypatch):
class _FakeDB:
def get_session_title(self, _key):
@@ -396,6 +424,34 @@ def test_session_title_rejects_empty_title_with_specific_error_code(monkeypatch)
server._sessions.pop("sid", None)
def test_session_title_set_maps_valueerror_to_user_error(monkeypatch):
class _FakeDB:
def get_session_title(self, _key):
return ""
def get_session(self, _key):
return {"id": _key}
def set_session_title(self, _key, _title):
raise ValueError("Title already in use")
server._sessions["sid"] = _session()
monkeypatch.setattr(server, "_get_db", lambda: _FakeDB())
try:
resp = server.handle_request(
{
"id": "1",
"method": "session.title",
"params": {"session_id": "sid", "title": "dup"},
}
)
assert "error" in resp
assert resp["error"]["code"] == 4022
assert "already in use" in resp["error"]["message"]
finally:
server._sessions.pop("sid", None)
def test_session_title_set_errors_when_row_lookup_fails_after_noop(monkeypatch):
class _FakeDB:
def get_session_title(self, _key):

View File

@@ -1765,7 +1765,21 @@ def _(rid, params: dict) -> dict:
if "title" not in params:
fallback = session.get("pending_title") or ""
try:
resolved_title = db.get_session_title(key) or fallback
resolved_title = db.get_session_title(key) or ""
if not resolved_title and fallback:
if db.set_session_title(key, fallback):
session["pending_title"] = None
resolved_title = fallback
else:
existing_row = db.get_session(key)
existing_title = ((existing_row or {}).get("title") or "").strip()
if existing_title == fallback:
session["pending_title"] = None
resolved_title = fallback
else:
resolved_title = fallback
elif resolved_title:
session["pending_title"] = None
except Exception:
resolved_title = fallback
return _ok(
@@ -1796,6 +1810,8 @@ def _(rid, params: dict) -> dict:
)
session["pending_title"] = title
return _ok(rid, {"pending": True, "title": title})
except ValueError as e:
return _err(rid, 4022, str(e))
except Exception as e:
return _err(rid, 5007, str(e))