Skip to content

Commit 98dee13

Browse files
committed
re-raising BreakPointException from pipeline.run()
1 parent 9030636 commit 98dee13

File tree

2 files changed

+7
-43
lines changed

2 files changed

+7
-43
lines changed

haystack/core/pipeline/pipeline.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from haystack import logging, tracing
1212
from haystack.core.component import Component
13-
from haystack.core.errors import PipelineInvalidResumeStateError, PipelineRuntimeError
13+
from haystack.core.errors import BreakpointException, PipelineInvalidResumeStateError, PipelineRuntimeError
1414
from haystack.core.pipeline.base import (
1515
_COMPONENT_INPUT,
1616
_COMPONENT_OUTPUT,
@@ -71,8 +71,14 @@ def _run_component(
7171
logger.info("Running component {component_name}", component_name=component_name)
7272
try:
7373
component_output = instance.run(**inputs)
74+
except BreakpointException as error:
75+
# Re-raise BreakpointException to preserve the original exception context
76+
# This is important when Agent components internally use Pipeline._run_component
77+
# and trigger breakpoints that need to bubble up to the main pipeline
78+
raise error
7479
except Exception as error:
7580
raise PipelineRuntimeError.from_exception(component_name, instance.__class__, error) from error
81+
7682
component_visits[component_name] += 1
7783

7884
if not isinstance(component_output, Mapping):

test/components/agents/test_agent_breakpoints_inside_pipeline.py

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -234,17 +234,6 @@ def test_chat_generator_breakpoint_in_pipeline_agent():
234234
assert e.state is not None
235235
assert "messages" in e.state
236236
assert e.results is not None
237-
except PipelineRuntimeError as e:
238-
# propagated exception to core Pipeline - assure that the cause is a PipelineBreakpointException
239-
if hasattr(e, "__cause__") and isinstance(e.__cause__, BreakpointException):
240-
original_exception = e.__cause__
241-
assert original_exception.component == "chat_generator"
242-
assert original_exception.state is not None
243-
assert "messages" in original_exception.state
244-
assert original_exception.results is not None
245-
else:
246-
# re-raise if it's a different PipelineRuntimeError - test failed
247-
raise
248237

249238
# verify that debug/state file was created
250239
chat_generator_state_files = list(Path(debug_path).glob("database_agent_chat_generator_*.json"))
@@ -269,17 +258,6 @@ def test_tool_breakpoint_in_pipeline_agent():
269258
assert e.state is not None
270259
assert "messages" in e.state
271260
assert e.results is not None
272-
except PipelineRuntimeError as e:
273-
# propagated exception to core Pipeline - assure that the cause is a PipelineBreakpointException
274-
if hasattr(e, "__cause__") and isinstance(e.__cause__, BreakpointException):
275-
original_exception = e.__cause__
276-
assert original_exception.component == "tool_invoker"
277-
assert original_exception.state is not None
278-
assert "messages" in original_exception.state
279-
assert original_exception.results is not None
280-
else:
281-
# re-raise if it's a different PipelineRuntimeError - test failed
282-
raise
283261

284262
# verify that debug/state file was created
285263
tool_invoker_state_files = list(Path(debug_path).glob("database_agent_tool_invoker_*.json"))
@@ -306,16 +284,6 @@ def test_agent_breakpoint_chat_generator_and_resume_pipeline():
306284
assert "messages" in e.state
307285
assert e.results is not None
308286

309-
except PipelineRuntimeError as e:
310-
if hasattr(e, "__cause__") and isinstance(e.__cause__, BreakpointException):
311-
original_exception = e.__cause__
312-
assert original_exception.component == "chat_generator"
313-
assert original_exception.state is not None
314-
assert "messages" in original_exception.state
315-
assert original_exception.results is not None
316-
else:
317-
raise
318-
319287
# verify that the state file was created
320288
chat_generator_state_files = list(Path(debug_path).glob("database_agent_chat_generator_*.json"))
321289
assert len(chat_generator_state_files) > 0, f"No chat_generator state files found in {debug_path}"
@@ -368,16 +336,6 @@ def test_agent_breakpoint_tool_and_resume_pipeline():
368336
assert "messages" in e.state
369337
assert e.results is not None
370338

371-
except PipelineRuntimeError as e:
372-
if hasattr(e, "__cause__") and isinstance(e.__cause__, BreakpointException):
373-
original_exception = e.__cause__
374-
assert original_exception.component == "tool_invoker"
375-
assert original_exception.state is not None
376-
assert "messages" in original_exception.state
377-
assert original_exception.results is not None
378-
else:
379-
raise
380-
381339
# verify that the state file was created
382340
tool_invoker_state_files = list(Path(debug_path).glob("database_agent_tool_invoker_*.json"))
383341
assert len(tool_invoker_state_files) > 0, f"No tool_invoker state files found in {debug_path}"

0 commit comments

Comments
 (0)