Skip to content

Commit 2642b82

Browse files
committed
fix(sandbox): normalize diagnostic tail limits
Signed-off-by: Paul Furgale <pfurgale@nvidia.com>
1 parent e5b9cbb commit 2642b82

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

src/nooa/runtime/sandbox/serialization.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525

2626
from nooa.agentdoc import TruncatingStringIO
2727
from nooa.config.truncation_config import DEFAULT_TRUNCATION_CONFIG
28-
from nooa.errors.formatting import _bound_preformatted_diagnostic, _hard_bound_text
28+
from nooa.errors.formatting import (
29+
_bound_preformatted_diagnostic,
30+
_diagnostic_budget,
31+
_hard_bound_text,
32+
)
2933
from nooa.runtime.sandbox.errors import CellSerializationError
3034

3135
# ``TruncatingStringIO`` adds a human-readable envelope around retained
@@ -53,7 +57,7 @@ def _bounded_error_message(
5357
) -> str:
5458
"""Apply the effective capture policy once to a raw message before IPC."""
5559
content_limit = _effective_error_limit(max_error)
56-
effective_tail = tail_chars if tail_chars is None or tail_chars < content_limit else None
60+
_, effective_tail = _diagnostic_budget(content_limit, tail_chars)
5761
if len(value) <= content_limit:
5862
return value
5963
stream = TruncatingStringIO(limit=content_limit, tail_chars=effective_tail)

tests/runtime/sandbox/test_error_serialization.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,19 @@ def test_invalid_error_limit_falls_back_to_default(invalid_limit: object) -> Non
199199
assert "Showing first 5,000 and last 5,000 chars" in dto.error.message
200200

201201

202+
@pytest.mark.parametrize("invalid_tail", [-1, True])
203+
def test_invalid_error_tail_falls_back_to_valid_split(invalid_tail: object) -> None:
204+
dto = result_to_dto(
205+
_result_with_error(RuntimeError("x" * 1_000)),
206+
max_error=100,
207+
tail_chars=invalid_tail, # type: ignore[arg-type]
208+
)
209+
210+
assert dto.error is not None
211+
assert "Showing first 50 and last 50 chars" in dto.error.message
212+
assert dto.error.message.endswith("x" * 50 + "\n</truncated-output>")
213+
214+
202215
def test_error_dto_text_respects_configured_capture_limit_before_transport_limit() -> None:
203216
"""Text above a custom content budget is truncated even if the DTO could carry it."""
204217
max_error = 100

0 commit comments

Comments
 (0)