fix(logging): replace stdlib-style exc_info kwargs with loguru opt(exception=)
Loguru has no exc_info kwarg: extra kwargs are str.format() arguments, so
logger.error(f"...{e}", exc_info=True) forces .format() on the rendered
message — any error text containing braces (e.g. a JSON error body) raises
KeyError FROM the log call itself, escaping the surrounding except block and
killing the caller (observed: whole agent turns dying in benchmark runs).
The intended traceback was also never logged, since exc_info is not a loguru
feature.
Batch fix of all 143 sites across 11 files:
logger.X(msg, exc_info=True) -> logger.opt(exception=True).X(msg)
(one exc_info=exc site -> opt(exception=exc))
Messages are byte-identical; with the kwarg gone loguru never calls
.format(), so brace-containing f-string messages are inert.
Verified: AST post-conditions per file, py_compile, import smoke of all
modules, behavioral equivalence of the 3 patterns, full unit suite (1549
passed) with a failure set identical to the pristine tree (22 pre-existing,
zero regressions).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Also add pixel-agents to the README acknowledgements.
This commit is contained in:
@@ -174,7 +174,7 @@ class OfficeServiceContext:
|
||||
try:
|
||||
wire(engine)
|
||||
except Exception:
|
||||
logger.debug("Failed to wire service project engine callbacks", exc_info=True)
|
||||
logger.opt(exception=True).debug("Failed to wire service project engine callbacks")
|
||||
return engine
|
||||
|
||||
async def activate_project(self, project_id: str) -> Any:
|
||||
|
||||
@@ -77,7 +77,7 @@ class ProjectService:
|
||||
if asyncio.iscoroutine(maybe):
|
||||
await maybe
|
||||
except Exception:
|
||||
logger.debug(f"Failed to close project store for {project_id}", exc_info=True)
|
||||
logger.opt(exception=True).debug(f"Failed to close project store for {project_id}")
|
||||
|
||||
async def list(self, *, active_project_id: str | None = None) -> ServiceResult:
|
||||
active = active_project_id or self.context.active_engine_project_id()
|
||||
@@ -247,7 +247,7 @@ class ProjectService:
|
||||
try:
|
||||
await active_engine.store.close()
|
||||
except Exception:
|
||||
logger.debug("Failed to close active project store before delete", exc_info=True)
|
||||
logger.opt(exception=True).debug("Failed to close active project store before delete")
|
||||
shutil.rmtree(str(projects_dir), ignore_errors=True)
|
||||
|
||||
workplace = self.context.project_workplace(project_id)
|
||||
@@ -263,7 +263,7 @@ class ProjectService:
|
||||
if asyncio.iscoroutine(maybe):
|
||||
await maybe
|
||||
except Exception:
|
||||
logger.debug(f"memory.delete_project failed for {project_id}", exc_info=True)
|
||||
logger.opt(exception=True).debug(f"memory.delete_project failed for {project_id}")
|
||||
|
||||
events = [ServiceEvent("project_deleted", {"project_id": project_id})]
|
||||
payload: dict[str, Any] = {"project_id": project_id, "deleted_channels": deleted_channels}
|
||||
|
||||
@@ -267,7 +267,7 @@ class SessionService:
|
||||
try:
|
||||
await store.save_task(task)
|
||||
except Exception:
|
||||
logger.debug("failed to mark company runtime stop state", exc_info=True)
|
||||
logger.opt(exception=True).debug("failed to mark company runtime stop state")
|
||||
|
||||
async def _clear_company_runtime_stop_state(self, *, engine: Any, task_ids: list[str]) -> None:
|
||||
store = getattr(engine, "store", None)
|
||||
@@ -297,7 +297,7 @@ class SessionService:
|
||||
try:
|
||||
await store.save_task(task)
|
||||
except Exception:
|
||||
logger.debug("failed to clear company runtime stop state", exc_info=True)
|
||||
logger.opt(exception=True).debug("failed to clear company runtime stop state")
|
||||
|
||||
def _normalize_requested_config(
|
||||
self,
|
||||
@@ -445,7 +445,7 @@ class SessionService:
|
||||
)
|
||||
events.append(ServiceEvent("collab_sync_push", collab))
|
||||
except Exception:
|
||||
logger.warning("create_session collab_sync build failed", exc_info=True)
|
||||
logger.opt(exception=True).warning("create_session collab_sync build failed")
|
||||
return ServiceResult(session_payload, events)
|
||||
|
||||
def _session_metadata(
|
||||
@@ -606,7 +606,7 @@ class SessionService:
|
||||
if int(message_count or 0) > 0:
|
||||
return "message_history"
|
||||
except Exception:
|
||||
logger.debug("Failed to inspect session message count for config lock", exc_info=True)
|
||||
logger.opt(exception=True).debug("Failed to inspect session message count for config lock")
|
||||
status = getattr(getattr(task, "status", None), "value", getattr(task, "status", None))
|
||||
status_value = str(status or "").strip().lower()
|
||||
if status_value and status_value != "pending":
|
||||
@@ -958,7 +958,7 @@ class SessionService:
|
||||
stop_intent_id=stop_intent_id,
|
||||
)
|
||||
except Exception:
|
||||
logger.warning("suspend_company_runtime failed during service stop", exc_info=True)
|
||||
logger.opt(exception=True).warning("suspend_company_runtime failed during service stop")
|
||||
if suspended is not None:
|
||||
for candidate in list(suspended.get("task_ids", []) or []):
|
||||
candidate_id = str(candidate or "").strip()
|
||||
@@ -1000,7 +1000,7 @@ class SessionService:
|
||||
},
|
||||
)
|
||||
except Exception:
|
||||
logger.debug("failed to insert company runtime stop system message", exc_info=True)
|
||||
logger.opt(exception=True).debug("failed to insert company runtime stop system message")
|
||||
payload = {
|
||||
**default_payload,
|
||||
"status": "suspended",
|
||||
|
||||
Reference in New Issue
Block a user