fix: stop leaking raw exception text to clients, log it server-side - #144
Open
shrdgn wants to merge 1 commit into
Open
fix: stop leaking raw exception text to clients, log it server-side#144shrdgn wants to merge 1 commit into
shrdgn wants to merge 1 commit into
Conversation
server.py's catch-all handler in chat_completions had no logging.getLogger call anywhere in the file, so a bug in the fusion path (KeyError, AttributeError, a pydantic error, etc.) vanished without a server-side trace and its str(exc) went verbatim into the client-facing JSON error body. Log the exception and return a generic message instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RUqjSHNBmuHjXmw7o9QKLz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
openfusion/server.pyhas zerologgingcalls anywhere in the file (confirmed via grep — every other module that needs it, e.g.router.py,upstream.py, has a module logger). The catch-allexcept Exceptioninchat_completions(previouslyserver.py:595-599) both:UpstreamError(str(exc)), whicherrors.pyputs verbatim into the client-facing JSONerror.messagefield. Any bug in the fusion path — aKeyError,AttributeError, a pydantic validation error, anything that isn't a real upstream failure — surfaced itsstr(exc)straight to the caller.This also mislabeled genuine internal bugs as
upstream_error(misleading for anyone debugging from the client side), though that error type is left as-is here since fixing that taxonomy is a separate, larger change.Fix: add a module logger (
_log = logging.getLogger(__name__), matching therouter.pyconvention) and call_log.exception(...)before responding with a generic, non-leaking message. The already-safe branches above it (OpenFusionError,json.JSONDecodeError) are untouched — this only changes the final catch-all for truly unexpected exceptions.Found via an automated repo-review scheduled task; verified by hand by reading
server.py's exception handling and confirming (via grep) it was the only module with no logger.How it was tested
ruff check .passes (my changed lines; two pre-existing, unrelated formatting/lint items elsewhere in the repo are untouched by this diff)pytest -qpasses (491 passed, no live network)tests/test_integration.py::test_chat_completions_unhandled_exception_is_logged_not_leakedasserts the client response no longer contains the raw exception text and that it's still captured server-side viacaplog. Also updatedtests/test_errors.py::test_unexpected_exception_returns_upstream_error, which previously asserted the leaky behavior as correct.mypy openfusion/server.pypasseslogging.exception)Notes for reviewers
Only
chat_completions's final catch-all is touched. The streaming path (_fusion_streametc.) already wraps its own try/except into an SSE error chunk with a generic-ish message, so it wasn't affected by this gap.Generated by Claude Code