@@ -488,6 +488,111 @@ def test_complete_workflow():
488488 print ("✓ test_complete_workflow passed" )
489489
490490
491+ # ============================================================================
492+ # Error Handling Tests
493+ # ============================================================================
494+
495+
496+ def _make_rearrange (agents , flow , ** kwargs ):
497+ return AgentRearrange (agents = agents , flow = flow , max_loops = 1 , ** kwargs )
498+
499+
500+ def test_missing_agent_raises ():
501+ """run() must raise when flow references a removed agent."""
502+ agents = create_sample_agents ()
503+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
504+ del r .agents ["WriterAgent" ]
505+
506+ with pytest .raises (ValueError , match = "not registered" ):
507+ r .run ("test" )
508+
509+
510+ def test_broken_conversation_raises ():
511+ """run() must raise when conversation is corrupted."""
512+ agents = create_sample_agents ()
513+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
514+ r .conversation .conversation_history = None
515+
516+ with pytest .raises ((TypeError , AttributeError )):
517+ r .run ("test" )
518+
519+
520+ def test_agent_error_raises ():
521+ """run() must raise when an agent's run() raises unexpectedly."""
522+ agents = create_sample_agents ()
523+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
524+
525+ def bad_run (* args , ** kwargs ):
526+ raise TypeError ("unexpected error in agent" )
527+
528+ r .agents ["WriterAgent" ].run = bad_run
529+
530+ with pytest .raises (TypeError , match = "unexpected error in agent" ):
531+ r .run ("test" )
532+
533+
534+ def test_callable_propagates ():
535+ """__call__ must raise, not return the exception object."""
536+ agents = create_sample_agents ()
537+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
538+ del r .agents ["WriterAgent" ]
539+
540+ with pytest .raises (ValueError , match = "not registered" ):
541+ r ("test" )
542+
543+
544+ def test_batch_run_propagates ():
545+ """batch_run must raise, not return None."""
546+ agents = create_sample_agents ()
547+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
548+ del r .agents ["WriterAgent" ]
549+
550+ with pytest .raises (ValueError , match = "not registered" ):
551+ r .batch_run (["test1" , "test2" ])
552+
553+
554+ def test_error_logged_once ():
555+ """_catch_error should fire exactly once per failure."""
556+ agents = create_sample_agents ()
557+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
558+ del r .agents ["WriterAgent" ]
559+
560+ call_count = 0
561+ original_catch = r ._catch_error
562+
563+ def counting_catch (e ):
564+ nonlocal call_count
565+ call_count += 1
566+ original_catch (e )
567+
568+ r ._catch_error = counting_catch
569+
570+ with pytest .raises (ValueError ):
571+ r .run ("test" )
572+
573+ assert call_count == 1 , f"_catch_error called { call_count } times, expected 1"
574+
575+
576+ def test_successful_run_returns_result ():
577+ """A successful run must return a non-None result."""
578+ agents = create_sample_agents ()
579+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
580+
581+ result = r .run ("What is 2+2?" )
582+ assert result is not None
583+ assert isinstance (result , str )
584+ assert len (result ) > 0
585+
586+
587+ def test_successful_callable_returns_result ():
588+ """__call__ on success must return a result."""
589+ agents = create_sample_agents ()
590+ r = _make_rearrange (agents , "ResearchAgent -> WriterAgent" )
591+
592+ result = r ("What is 2+2?" )
593+ assert result is not None
594+
595+
491596def main ():
492597 """Run all tests."""
493598 tests = [
@@ -512,6 +617,14 @@ def main():
512617 test_concurrent_run ,
513618 test_to_dict ,
514619 test_complete_workflow ,
620+ test_missing_agent_raises ,
621+ test_broken_conversation_raises ,
622+ test_agent_error_raises ,
623+ test_callable_propagates ,
624+ test_batch_run_propagates ,
625+ test_error_logged_once ,
626+ test_successful_run_returns_result ,
627+ test_successful_callable_returns_result ,
515628 ]
516629
517630 print ("=" * 60 )
0 commit comments