Skip to content

Commit 0aa7388

Browse files
lchoquelclaude
andcommitted
fix: raise instead of printing None when hello_world output lacks text
find_main_content() can return a content dict that has no `text` key (schema mismatch or unexpected API output). Previously hello_world() did `print(content.get("text"))`, which printed `None` and exited successfully — a silent failure that the API-hitting e2e test could not catch. Guard the value: raise RuntimeError unless `text` is a non-empty string, mirroring the existing `content is None` check. Add tests/unit/test_hello_world.py — an offline regression test (no pipelex_api/inference marker, runs in CI) that patches the API client with a hand-rolled async fake and asserts the missing-text path raises. Resolves greptile review comment on PR #57. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ry9KASVKXj1SVgJqtrSMxh
1 parent 333783a commit 0aa7388

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

my_project/hello_world.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ async def hello_world() -> None:
6363
if content is None:
6464
raise RuntimeError("The pipeline returned no output content.")
6565

66+
generated_text = content.get("text")
67+
if not isinstance(generated_text, str) or not generated_text:
68+
raise RuntimeError("The pipeline returned no text output.")
69+
6670
print("Your first Pipelex output:\n")
67-
print(content.get("text"))
71+
print(generated_text)
6872

6973

7074
if __name__ == "__main__":

tests/unit/test_hello_world.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from typing import Any
2+
3+
import pytest
4+
from pytest import CaptureFixture, MonkeyPatch
5+
6+
from my_project import hello_world as hello_world_module
7+
from my_project.hello_world import hello_world
8+
9+
10+
class _FakeResults:
11+
# Minimal stand-in for pipelex_sdk.runs.RunResults: find_main_content()
12+
# reads only `.main_stuff` / `.pipe_output`.
13+
def __init__(self, main_stuff: Any) -> None:
14+
self.main_stuff = main_stuff
15+
self.pipe_output = None
16+
17+
18+
class _FakeClient:
19+
# Stand-in for PipelexAPIClient used as `async with ... as client`, so no
20+
# network is touched: __aenter__ returns the client and start_and_wait
21+
# yields the canned results.
22+
def __init__(self, results: _FakeResults) -> None:
23+
self._results = results
24+
25+
async def __aenter__(self) -> "_FakeClient":
26+
return self
27+
28+
async def __aexit__(self, *_exc_info: object) -> None:
29+
return None
30+
31+
async def start_and_wait(self, *, pipe_code: str, mthds_contents: list[str]) -> _FakeResults:
32+
return self._results
33+
34+
35+
class TestHelloWorldOutput:
36+
def _patch_client(self, monkeypatch: MonkeyPatch, main_stuff: Any) -> None:
37+
results = _FakeResults(main_stuff=main_stuff)
38+
monkeypatch.setattr(hello_world_module, "PipelexAPIClient", lambda: _FakeClient(results))
39+
40+
async def test_missing_text_raises(self, monkeypatch: MonkeyPatch):
41+
# A valid content dict without a `text` key must fail loudly instead of
42+
# printing `None` and exiting successfully.
43+
self._patch_client(monkeypatch, main_stuff={"not_text": "oops"})
44+
45+
with pytest.raises(RuntimeError, match="no text output"):
46+
await hello_world()
47+
48+
async def test_valid_text_prints(self, monkeypatch: MonkeyPatch, capsys: CaptureFixture[str]):
49+
self._patch_client(monkeypatch, main_stuff={"text": "a generated haiku"})
50+
51+
await hello_world()
52+
53+
assert "a generated haiku" in capsys.readouterr().out

0 commit comments

Comments
 (0)