-
Notifications
You must be signed in to change notification settings - Fork 751
fix: Truncate HttpError message to first 8192 characters #5020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Truncate HttpError message to first 8192 characters #5020
Conversation
|
👋 Hi siclait! Thank you for contributing to ai-dynamo/dynamo. Just a reminder: The 🚀 |
616b10b to
1696311
Compare
WalkthroughThe changes enhance HttpError exception handling across Python and Rust bindings by introducing stricter validation for HTTP error codes and messages, implementing message truncation at the Python layer, and replacing duck-typing with PyO3's typed extraction mechanism in the Rust layer for improved robustness. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/bindings/python/tests/test_http_error.py (1)
4-5: Pipeline failure: isort hook modified imports.The pre-commit isort hook failed, indicating import ordering was corrected automatically. Please commit the isort changes.
🧹 Nitpick comments (3)
lib/bindings/python/rust/http.rs (1)
162-164: Outdated comment: refers to duck typing but code now uses typed extraction.The comment describes the old approach. Consider updating it to reflect the current typed extraction via
FromPyObject.Suggested fix
- // With the Stable ABI, we can't subclass Python's built-in exceptions in PyO3, so instead we - // implement the exception in Python and use duck typing / assume that it's an HttpError if - // the code and message are present. + // With the Stable ABI, we can't subclass Python's built-in exceptions in PyO3, so we + // implement the exception in Python and extract the code and message fields directly.lib/bindings/python/src/dynamo/llm/exceptions.py (2)
11-14: Consider explicit bool rejection.
isinstance(True, int)returnsTruein Python sinceboolis a subclass ofint. This meansHttpError(True, "msg")would pass validation withcode=1. If this is unintended, add an explicit check.Optional fix if bool should be rejected
- if not isinstance(code, int): + if not isinstance(code, int) or isinstance(code, bool): raise ValueError("HttpError status code must be an integer")
22-26: Preferlogging.warning()overprint()for library code.Using
print()in library code can interfere with application output and isn't configurable. Consider using theloggingmodule instead.Suggested fix
+import logging + +logger = logging.getLogger(__name__) + _MAX_MESSAGE_LENGTH = 8192if len(message) > _MAX_MESSAGE_LENGTH: - print( + logger.warning( f"HttpError message length {len(message)} exceeds max length {_MAX_MESSAGE_LENGTH}, truncating..." ) message = message[: (_MAX_MESSAGE_LENGTH - 3)] + "..."
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
lib/bindings/python/rust/http.rs(2 hunks)lib/bindings/python/src/dynamo/llm/exceptions.py(1 hunks)lib/bindings/python/tests/test_http_error.py(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: PeaBrane
Repo: ai-dynamo/dynamo PR: 3155
File: components/backends/vllm/src/dynamo/vllm/main.py:228-233
Timestamp: 2025-09-21T01:40:52.456Z
Learning: In the dynamo codebase, error handling for distributed runtime client initialization (like runtime.namespace().component().endpoint().client()) is handled at the Rust level in the distributed runtime bindings, so Python-level try/catch blocks are not needed and would be redundant.
📚 Learning: 2025-08-21T17:23:02.836Z
Learnt from: michaelfeil
Repo: ai-dynamo/dynamo PR: 2591
File: lib/bindings/python/rust/http.rs:0-0
Timestamp: 2025-08-21T17:23:02.836Z
Learning: In lib/bindings/python/rust/http.rs, the enable_endpoint method uses EndpointType::all() to dynamically support all available endpoint types with case-insensitive matching, which is more maintainable than hardcoded match statements for endpoint type mappings.
Applied to files:
lib/bindings/python/rust/http.rs
📚 Learning: 2025-06-13T22:07:24.843Z
Learnt from: kthui
Repo: ai-dynamo/dynamo PR: 1424
File: lib/runtime/src/pipeline/network/egress/push_router.rs:204-209
Timestamp: 2025-06-13T22:07:24.843Z
Learning: The codebase uses async-nats version 0.40, not the older nats crate. Error handling should use async_nats::error::Error variants, not nats::Error variants.
Applied to files:
lib/bindings/python/rust/http.rs
🧬 Code graph analysis (2)
lib/bindings/python/rust/http.rs (1)
lib/bindings/python/src/dynamo/llm/exceptions.py (1)
HttpError(9-31)
lib/bindings/python/tests/test_http_error.py (1)
lib/bindings/python/src/dynamo/llm/exceptions.py (1)
HttpError(9-31)
🪛 GitHub Actions: Pre Merge Validation of (ai-dynamo/dynamo/refs/pull/5020/merge) by siclait.
lib/bindings/python/tests/test_http_error.py
[error] 1-1: isort hook failed: files were modified by this hook. The pre-commit hook updated the file to satisfy import sorting.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: clippy (lib/bindings/python)
- GitHub Check: tests (lib/runtime/examples)
- GitHub Check: tests (.)
- GitHub Check: clippy (launch/dynamo-run)
- GitHub Check: tests (launch/dynamo-run)
- GitHub Check: tests (lib/bindings/python)
- GitHub Check: clippy (.)
- GitHub Check: Build and Test - dynamo
🔇 Additional comments (6)
lib/bindings/python/rust/http.rs (2)
141-145: LGTM!The
HttpErrorstruct withFromPyObjectderive cleanly replaces the previous duck-typing approach. The field types correctly match the Python-sideHttpErrorattributes.
165-171: LGTM!The typed extraction via
FromPyObjectis cleaner and more robust than the previous attribute-by-attribute extraction. The newline/carriage return sanitization for SSE compatibility is correctly preserved.lib/bindings/python/tests/test_http_error.py (2)
22-25: LGTM!Good test case validating that non-string message types raise
ValueError. Usingbytesas the invalid type is a sensible edge case since it's a common confusion withstr.
28-35: LGTM!The truncation test correctly validates:
- Message length is capped at 8192 characters
- The truncated content (first 8189 chars) is present in the string representation
- The trailing character "B" is excluded
lib/bindings/python/src/dynamo/llm/exceptions.py (2)
6-6: LGTM!Good choice defining the max length as a module-level constant for maintainability. The 8KB limit is reasonable for error messages.
10-31: Overall implementation looks solid.The validation and truncation logic correctly addresses the PR objective of preventing
ValueErrorfrom omitting the original message. The truncation preserves context while staying within bounds.
Signed-off-by: Phillippe Siclait <[email protected]>
Signed-off-by: Phillippe Siclait <[email protected]>
09e6a21 to
e88b6c8
Compare
|
/ok to test e88b6c8 |
|
We definitely should return better error messages, but I am actually curious what is the case where we create an HttpError that is >8K in size? |
|
Syncing with latest main to pull in this commit to fix vllm arm failure: siclait@676ce43 |
|
/ok to test c0d460d |
That's a good question. I just saw the ValueError — I'll find out what the cause was. |
kthui
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for improving the error message handling.
|
@siclait I'm going to merge this to avoid it getting stale or have merge conflicts over the holidays since it seems like a net win regardless, but please do follow up on the use case / scenario as it would be good to get to the bottom of as well:
|
Overview:
Prior to this fix, instantiating an
HttpErrorwith a long error message would yield aValueErrorthat doesn't include any of the original message, making it more difficult to trace the source of the issue.With this fix, we truncate the message instead to maintain some context.
Details:
A few changes:
codeandmessagefrom thepy_errand drops thename=HttpErrorcheck.Where should the reviewer start?
The truncation logic is in
exceptions.pyRelated Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
N/A
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.