33 *
44 * @group unit/tracer/all
55 */
6-
76import { captureLambdaHandler } from '../../src/middleware/middy' ;
87import middy from '@middy/core' ;
98import { Tracer } from './../../src' ;
@@ -13,6 +12,7 @@ import {
1312 setContextMissingStrategy ,
1413 Subsegment ,
1514} from 'aws-xray-sdk-core' ;
15+ import { cleanupMiddlewares } from '@aws-lambda-powertools/commons/lib/middleware' ;
1616
1717jest . spyOn ( console , 'debug' ) . mockImplementation ( ( ) => null ) ;
1818jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => null ) ;
@@ -306,4 +306,66 @@ describe('Middy middleware', () => {
306306 'hello-world'
307307 ) ;
308308 } ) ;
309+
310+ test ( 'when enabled, and another middleware returns early, it still closes and restores the segments correctly' , async ( ) => {
311+ // Prepare
312+ const tracer = new Tracer ( ) ;
313+ const setSegmentSpy = jest
314+ . spyOn ( tracer . provider , 'setSegment' )
315+ . mockImplementation ( ( ) => ( { } ) ) ;
316+ jest . spyOn ( tracer , 'annotateColdStart' ) . mockImplementation ( ( ) => ( { } ) ) ;
317+ jest
318+ . spyOn ( tracer , 'addServiceNameAnnotation' )
319+ . mockImplementation ( ( ) => ( { } ) ) ;
320+ const facadeSegment1 = new Segment ( 'facade' ) ;
321+ const handlerSubsegment1 = new Subsegment ( '## index.handlerA' ) ;
322+ jest
323+ . spyOn ( facadeSegment1 , 'addNewSubsegment' )
324+ . mockImplementation ( ( ) => handlerSubsegment1 ) ;
325+ const facadeSegment2 = new Segment ( 'facade' ) ;
326+ const handlerSubsegment2 = new Subsegment ( '## index.handlerB' ) ;
327+ jest
328+ . spyOn ( facadeSegment2 , 'addNewSubsegment' )
329+ . mockImplementation ( ( ) => handlerSubsegment2 ) ;
330+ jest
331+ . spyOn ( tracer . provider , 'getSegment' )
332+ . mockImplementationOnce ( ( ) => facadeSegment1 )
333+ . mockImplementationOnce ( ( ) => facadeSegment2 ) ;
334+ const myCustomMiddleware = ( ) : middy . MiddlewareObj => {
335+ const before = async (
336+ request : middy . Request
337+ ) : Promise < undefined | string > => {
338+ // Return early on the second invocation
339+ if ( request . event . idx === 1 ) {
340+ // Cleanup Powertools resources
341+ await cleanupMiddlewares ( request ) ;
342+
343+ // Then return early
344+ return 'foo' ;
345+ }
346+ } ;
347+
348+ return {
349+ before,
350+ } ;
351+ } ;
352+ const handler = middy ( ( ) : void => {
353+ console . log ( 'Hello world!' ) ;
354+ } )
355+ . use ( captureLambdaHandler ( tracer , { captureResponse : false } ) )
356+ . use ( myCustomMiddleware ( ) ) ;
357+
358+ // Act
359+ await handler ( { idx : 0 } , context ) ;
360+ await handler ( { idx : 1 } , context ) ;
361+
362+ // Assess
363+ // Check that the subsegments are closed
364+ expect ( handlerSubsegment1 . isClosed ( ) ) . toBe ( true ) ;
365+ expect ( handlerSubsegment2 . isClosed ( ) ) . toBe ( true ) ;
366+ // Check that the segments are restored
367+ expect ( setSegmentSpy ) . toHaveBeenCalledTimes ( 4 ) ;
368+ expect ( setSegmentSpy ) . toHaveBeenNthCalledWith ( 2 , facadeSegment1 ) ;
369+ expect ( setSegmentSpy ) . toHaveBeenNthCalledWith ( 4 , facadeSegment2 ) ;
370+ } ) ;
309371} ) ;
0 commit comments