@@ -40,16 +40,20 @@ describe('Class: BaseRouter', () => {
4040 }
4141 }
4242
43- public async resolve ( event : unknown , context : Context ) : Promise < unknown > {
43+ public async resolve (
44+ event : unknown ,
45+ context : Context ,
46+ options ?: any
47+ ) : Promise < unknown > {
4448 this . #isEvent( event ) ;
4549 const { method, path } = event ;
4650 const route = this . routeRegistry . resolve ( method , path ) ;
4751 try {
4852 if ( route == null )
4953 throw new NotFoundError ( `Route ${ method } ${ path } not found` ) ;
50- return route . handler ( event , context ) ;
54+ return await route . handler ( event , context ) ;
5155 } catch ( error ) {
52- return await this . handleError ( error as Error ) ;
56+ return await this . handleError ( error as Error , options ) ;
5357 }
5458 }
5559 }
@@ -589,5 +593,181 @@ describe('Class: BaseRouter', () => {
589593 // Assess
590594 expect ( result . headers . get ( 'Content-Type' ) ) . toBe ( 'application/json' ) ;
591595 } ) ;
596+
597+ describe ( 'decorators' , ( ) => {
598+ it ( 'works with errorHandler decorator' , async ( ) => {
599+ // Prepare
600+ const app = new TestResolver ( ) ;
601+
602+ class Lambda {
603+ @app . errorHandler ( BadRequestError )
604+ public async handleBadRequest ( error : BadRequestError ) {
605+ return {
606+ statusCode : HttpErrorCodes . BAD_REQUEST ,
607+ error : 'Bad Request' ,
608+ message : `Decorated: ${ error . message } ` ,
609+ } ;
610+ }
611+
612+ @app . get ( '/test' )
613+ public async getTest ( ) {
614+ throw new BadRequestError ( 'test error' ) ;
615+ }
616+
617+ public async handler ( event : unknown , context : Context ) {
618+ return app . resolve ( event , context ) ;
619+ }
620+ }
621+
622+ const lambda = new Lambda ( ) ;
623+
624+ // Act
625+ const result = ( await lambda . handler (
626+ { path : '/test' , method : 'GET' } ,
627+ context
628+ ) ) as Response ;
629+
630+ // Assess
631+ expect ( result ) . toBeInstanceOf ( Response ) ;
632+ expect ( result . status ) . toBe ( HttpErrorCodes . BAD_REQUEST ) ;
633+ expect ( await result . text ( ) ) . toBe (
634+ JSON . stringify ( {
635+ statusCode : HttpErrorCodes . BAD_REQUEST ,
636+ error : 'Bad Request' ,
637+ message : 'Decorated: test error' ,
638+ } )
639+ ) ;
640+ } ) ;
641+
642+ it ( 'works with notFound decorator' , async ( ) => {
643+ // Prepare
644+ const app = new TestResolver ( ) ;
645+
646+ class Lambda {
647+ @app . notFound ( )
648+ public async handleNotFound ( error : NotFoundError ) {
649+ return {
650+ statusCode : HttpErrorCodes . NOT_FOUND ,
651+ error : 'Not Found' ,
652+ message : `Decorated: ${ error . message } ` ,
653+ } ;
654+ }
655+
656+ public async handler ( event : unknown , context : Context ) {
657+ return app . resolve ( event , context ) ;
658+ }
659+ }
660+
661+ const lambda = new Lambda ( ) ;
662+
663+ // Act
664+ const result = ( await lambda . handler (
665+ { path : '/nonexistent' , method : 'GET' } ,
666+ context
667+ ) ) as Response ;
668+
669+ // Assess
670+ expect ( result ) . toBeInstanceOf ( Response ) ;
671+ expect ( result . status ) . toBe ( HttpErrorCodes . NOT_FOUND ) ;
672+ expect ( await result . text ( ) ) . toBe (
673+ JSON . stringify ( {
674+ statusCode : HttpErrorCodes . NOT_FOUND ,
675+ error : 'Not Found' ,
676+ message : 'Decorated: Route GET /nonexistent not found' ,
677+ } )
678+ ) ;
679+ } ) ;
680+
681+ it ( 'works with methodNotAllowed decorator' , async ( ) => {
682+ // Prepare
683+ const app = new TestResolver ( ) ;
684+
685+ class Lambda {
686+ @app . methodNotAllowed ( )
687+ public async handleMethodNotAllowed ( error : MethodNotAllowedError ) {
688+ return {
689+ statusCode : HttpErrorCodes . METHOD_NOT_ALLOWED ,
690+ error : 'Method Not Allowed' ,
691+ message : `Decorated: ${ error . message } ` ,
692+ } ;
693+ }
694+
695+ @app . get ( '/test' )
696+ public async getTest ( ) {
697+ throw new MethodNotAllowedError ( 'POST not allowed' ) ;
698+ }
699+
700+ public async handler ( event : unknown , context : Context ) {
701+ return app . resolve ( event , context ) ;
702+ }
703+ }
704+
705+ const lambda = new Lambda ( ) ;
706+
707+ // Act
708+ const result = ( await lambda . handler (
709+ { path : '/test' , method : 'GET' } ,
710+ context
711+ ) ) as Response ;
712+
713+ // Assess
714+ expect ( result ) . toBeInstanceOf ( Response ) ;
715+ expect ( result . status ) . toBe ( HttpErrorCodes . METHOD_NOT_ALLOWED ) ;
716+ expect ( await result . text ( ) ) . toBe (
717+ JSON . stringify ( {
718+ statusCode : HttpErrorCodes . METHOD_NOT_ALLOWED ,
719+ error : 'Method Not Allowed' ,
720+ message : 'Decorated: POST not allowed' ,
721+ } )
722+ ) ;
723+ } ) ;
724+
725+ it ( 'preserves scope when using error handler decorators' , async ( ) => {
726+ // Prepare
727+ const app = new TestResolver ( ) ;
728+
729+ class Lambda {
730+ public scope = 'scoped' ;
731+
732+ @app . errorHandler ( BadRequestError )
733+ public async handleBadRequest ( error : BadRequestError ) {
734+ return {
735+ statusCode : HttpErrorCodes . BAD_REQUEST ,
736+ error : 'Bad Request' ,
737+ message : `${ this . scope } : ${ error . message } ` ,
738+ } ;
739+ }
740+
741+ @app . get ( '/test' )
742+ public async getTest ( ) {
743+ throw new BadRequestError ( 'test error' ) ;
744+ }
745+
746+ public async handler ( event : unknown , context : Context ) {
747+ return app . resolve ( event , context , { scope : this } ) ;
748+ }
749+ }
750+
751+ const lambda = new Lambda ( ) ;
752+ const handler = lambda . handler . bind ( lambda ) ;
753+
754+ // Act
755+ const result = ( await handler (
756+ { path : '/test' , method : 'GET' } ,
757+ context
758+ ) ) as Response ;
759+
760+ // Assess
761+ expect ( result ) . toBeInstanceOf ( Response ) ;
762+ expect ( result . status ) . toBe ( HttpErrorCodes . BAD_REQUEST ) ;
763+ expect ( await result . text ( ) ) . toBe (
764+ JSON . stringify ( {
765+ statusCode : HttpErrorCodes . BAD_REQUEST ,
766+ error : 'Bad Request' ,
767+ message : 'scoped: test error' ,
768+ } )
769+ ) ;
770+ } ) ;
771+ } ) ;
592772 } ) ;
593773} ) ;
0 commit comments