@@ -497,3 +497,77 @@ describe('step-handler 409 handling', () => {
497497 } ) ;
498498 } ) ;
499499} ) ;
500+
501+ describe ( 'step-handler max deliveries' , ( ) => {
502+ beforeEach ( ( ) => {
503+ vi . clearAllMocks ( ) ;
504+ vi . mocked ( getStepFunction ) . mockReturnValue ( mockStepFn ) ;
505+ mockStepFn . mockReset ( ) . mockResolvedValue ( 'step-result' ) ;
506+ mockStepFn . maxRetries = 3 ;
507+ mockQueueMessage . mockResolvedValue ( undefined ) ;
508+ vi . mocked ( getWorld ) . mockReturnValue ( {
509+ events : { create : mockEventsCreate } ,
510+ queue : mockQueue ,
511+ getEncryptionKeyForRun : vi . fn ( ) . mockResolvedValue ( undefined ) ,
512+ } as any ) ;
513+ mockEventsCreate . mockReset ( ) . mockResolvedValue ( {
514+ step : {
515+ stepId : 'step_abc' ,
516+ status : 'running' ,
517+ attempt : 1 ,
518+ startedAt : new Date ( ) ,
519+ input : [ ] ,
520+ } ,
521+ event : { } ,
522+ } ) ;
523+ } ) ;
524+
525+ afterEach ( ( ) => {
526+ vi . restoreAllMocks ( ) ;
527+ } ) ;
528+
529+ it ( 'should post step_failed and re-queue workflow when delivery count exceeds max' , async ( ) => {
530+ const result = await capturedHandler (
531+ createMessage ( ) ,
532+ { ...createMetadata ( 'myStep' ) , attempt : 65 }
533+ ) ;
534+
535+ expect ( result ) . toBeUndefined ( ) ;
536+ expect ( mockEventsCreate ) . toHaveBeenCalledWith (
537+ 'wrun_test123' ,
538+ expect . objectContaining ( {
539+ eventType : 'step_failed' ,
540+ correlationId : 'step_abc' ,
541+ } )
542+ ) ;
543+ expect ( mockQueueMessage ) . toHaveBeenCalled ( ) ;
544+ expect ( mockRuntimeLogger . error ) . toHaveBeenCalledWith (
545+ expect . stringContaining ( 'exceeded max deliveries' ) ,
546+ expect . objectContaining ( { workflowRunId : 'wrun_test123' } )
547+ ) ;
548+ } ) ;
549+
550+ it ( 'should consume message silently when step_failed fails with EntityConflictError' , async ( ) => {
551+ mockEventsCreate . mockRejectedValue (
552+ new EntityConflictError ( 'Step already completed' )
553+ ) ;
554+
555+ const result = await capturedHandler (
556+ createMessage ( ) ,
557+ { ...createMetadata ( 'myStep' ) , attempt : 65 }
558+ ) ;
559+
560+ expect ( result ) . toBeUndefined ( ) ;
561+ expect ( mockStepFn ) . not . toHaveBeenCalled ( ) ;
562+ } ) ;
563+
564+ it ( 'should not trigger max deliveries check when under limit' , async ( ) => {
565+ const result = await capturedHandler (
566+ createMessage ( ) ,
567+ { ...createMetadata ( 'myStep' ) , attempt : 64 }
568+ ) ;
569+
570+ // Should proceed normally (step function executes)
571+ expect ( mockStepFn ) . toHaveBeenCalled ( ) ;
572+ } ) ;
573+ } ) ;
0 commit comments