@@ -183,9 +183,9 @@ describe('Test baseQueueHandler', function () {
183183 DemoHandler . prototype . afterDlq = originalAfterDlq ;
184184 } ) ;
185185
186- it ( 'should add raw buffer to dlq when afterDlq throws to prevent double-encoding ' , async function ( ) {
186+ it ( 'should not duplicate dlq message when afterDlq throws after successful publish ' , async function ( ) {
187187 const handler = new DemoHandler ( this . name , rabbit , {
188- retries : 2 ,
188+ retries : 1 ,
189189 retryDelay : 10
190190 } ) ;
191191 await handler . created ;
@@ -207,19 +207,49 @@ describe('Test baseQueueHandler', function () {
207207
208208 await rabbit . publish ( this . name , { test : 'data' } , { correlationId : '3' } ) ;
209209 const publish = sandbox . spy ( handler . rabbit , 'publish' ) ;
210- await new Promise ( resolve => setTimeout ( resolve , 300 ) ) ;
210+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
211211
212212 afterDlq . calledOnce . should . be . true ( ) ;
213+ publish . calledOnce . should . be . true ( ) ;
214+ dlqMessages . length . should . equal ( 1 ) ;
215+ dlqMessages [ 0 ] . event . should . eql ( { test : 'data' } ) ;
216+ } ) ;
217+
218+ it ( 'should publish raw buffer to dlq when first publish fails' , async function ( ) {
219+ const handler = new DemoHandler ( this . name , rabbit , {
220+ retries : 1 ,
221+ retryDelay : 10
222+ } ) ;
223+ await handler . created ;
224+ handler . handle = sandbox . spy ( ( ) => {
225+ throw new Error ( 'test error' ) ;
226+ } ) ;
227+ const afterDlq = ( handler . afterDlq = sandbox . spy ( ) ) ;
228+
229+ const dlqMessages : any [ ] = [ ] ;
230+ await rabbit . subscribe ( this . name + '_dlq' , ( msg , ack ) => {
231+ dlqMessages . push ( { event : JSON . parse ( msg . content . toString ( ) ) , content : msg . content } ) ;
232+ ack ( null ) ;
233+ } ) ;
234+
235+ await rabbit . publish ( this . name , { test : 'data' } , { correlationId : '5' } ) ;
236+ const originalPublish = handler . rabbit . publish . bind ( handler . rabbit ) ;
237+ let publishCallCount = 0 ;
238+ const publish = sandbox . stub ( handler . rabbit , 'publish' ) . callsFake ( ( ...args ) => {
239+ publishCallCount ++ ;
240+ if ( publishCallCount === 1 ) {
241+ return Promise . reject ( new Error ( 'broker rejected' ) ) ;
242+ }
243+ return originalPublish ( ...args ) ;
244+ } ) ;
245+ await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
246+
213247 publish . calledTwice . should . be . true ( ) ;
214- const fallbackPayload = publish . args [ publish . callCount - 1 ] [ 1 ] ;
248+ const fallbackPayload = publish . args [ 1 ] [ 1 ] ;
215249 Buffer . isBuffer ( fallbackPayload ) . should . be . true ( ) ;
216250 fallbackPayload . toString ( ) . should . eql ( '{"test":"data"}' ) ;
217-
218- // TODO: This flow also produces duplicate messages on the DLQ,
219- // to be investigated and handled on the next PR
220- dlqMessages . length . should . equal ( 2 ) ;
251+ dlqMessages . length . should . equal ( 1 ) ;
221252 dlqMessages [ 0 ] . event . should . eql ( { test : 'data' } ) ;
222- dlqMessages [ 1 ] . event . should . eql ( { test : 'data' } ) ;
223253 } ) ;
224254
225255 it ( 'should add to dlq after x retries and get error response even if afterDlq throws error' , async function ( ) {
0 commit comments