@@ -366,178 +366,185 @@ class API {
366366 }
367367 }
368368
369+ // If first time through, process error middleware
369370 if ( response . _state === 'processing' ) {
371+ // Flag error state (this will avoid infinite error loops)
370372 response . _state = 'error' ;
373+
374+ // Execute error middleware
371375 for ( const err of this . _errors ) {
372376 if ( response . _state === 'done' ) break ;
373- await new Promise ( async ( r ) => {
374- let rtn = await err ( e , response . _request , response , ( ) => {
375- r ( ) ;
376- } ) ;
377- if ( rtn ) response . send ( rtn ) ;
377+ // Promisify error middleware
378+ // TODO: using async within a promise is an antipattern, therefore we need to refactor this asap
379+ // eslint-disable-next-line no-async-promise-executorawait new Promise(async (r) => {
380+ let rtn = await err ( e , response . _request , response , ( ) => {
378381 r ( ) ;
379382 } ) ;
380- }
383+ if ( rtn ) response . send ( rtn ) ;
384+ r ( ) ;
385+ } ) ;
381386 }
387+ }
382388
383- if ( response . _state !== 'done' ) response . json ( { error : message } ) ;
389+ // Throw standard error unless callback has already been executed
390+ if ( response . _state !== 'done' ) response . json ( { error : message } ) ;
384391 } // end catch
385392
386393 // Custom callback
387394 async _callback ( err , res , response ) {
388- // Set done status
389- response . _state = 'done' ;
390-
391- // Execute finally
392- await this . _finally ( response . _request , response ) ;
393-
394- // Output logs
395- response . _request . _logs . forEach ( ( log ) => {
396- this . _logger . logger (
397- JSON . stringify (
398- this . _logger . detail
399- ? this . _logger . format ( log , response . _request , response )
400- : log
401- )
402- ) ;
403- } ) ;
404-
405- // Generate access log
406- if (
407- ( this . _logger . access || response . _request . _logs . length > 0 ) &&
408- this . _logger . access !== 'never'
409- ) {
410- let access = Object . assign (
411- this . _logger . log (
412- 'access' ,
413- undefined ,
414- response . _request ,
415- response . _request . context
416- ) ,
417- {
418- statusCode : res . statusCode ,
419- coldStart : response . _request . coldStart ,
420- count : response . _request . requestCount ,
421- }
422- ) ;
423- this . _logger . logger (
424- JSON . stringify ( this . _logger . format ( access , response . _request , response ) )
425- ) ;
426- }
427-
428- // Reset global error code
429- this . _errorStatus = 500 ;
430-
431- // Execute the primary callback
432- typeof this . _cb === 'function' && this . _cb ( err , res ) ;
433- } // end _callback
434-
435- // Middleware handler
436- use ( ...args ) {
437- // Extract routes
438- let routes =
439- typeof args [ 0 ] === 'string'
440- ? Array . of ( args . shift ( ) )
441- : Array . isArray ( args [ 0 ] )
442- ? args . shift ( )
443- : [ '/*' ] ;
444-
445- // Init middleware stack
446- let middleware = [ ] ;
447-
448- // Add func args as middleware
449- for ( let arg in args ) {
450- if ( typeof args [ arg ] === 'function' ) {
451- if ( args [ arg ] . length === 3 ) {
452- middleware . push ( args [ arg ] ) ;
453- } else if ( args [ arg ] . length === 4 ) {
454- this . _errors . push ( args [ arg ] ) ;
455- } else {
456- throw new ConfigurationError (
457- 'Middleware must have 3 or 4 parameters'
458- ) ;
459- }
395+ // Set done status
396+ response . _state = 'done' ;
397+
398+ // Execute finally
399+ await this . _finally ( response . _request , response ) ;
400+
401+ // Output logs
402+ response . _request . _logs . forEach ( ( log ) => {
403+ this . _logger . logger (
404+ JSON . stringify (
405+ this . _logger . detail
406+ ? this . _logger . format ( log , response . _request , response )
407+ : log
408+ )
409+ ) ;
410+ } ) ;
411+
412+ // Generate access log
413+ if (
414+ ( this . _logger . access || response . _request . _logs . length > 0 ) &&
415+ this . _logger . access !== 'never'
416+ ) {
417+ let access = Object . assign (
418+ this . _logger . log (
419+ 'access' ,
420+ undefined ,
421+ response . _request ,
422+ response . _request . context
423+ ) ,
424+ {
425+ statusCode : res . statusCode ,
426+ coldStart : response . _request . coldStart ,
427+ count : response . _request . requestCount ,
460428 }
461- }
429+ ) ;
430+ this . _logger . logger (
431+ JSON . stringify ( this . _logger . format ( access , response . _request , response ) )
432+ ) ;
433+ }
462434
463- // Add middleware for all methods
464- if ( middleware . length > 0 ) {
465- routes . forEach ( ( route ) => {
466- this . METHOD ( '__MW__' , route , ...middleware ) ;
467- } ) ;
435+ // Reset global error code
436+ this . _errorStatus = 500 ;
437+
438+ // Execute the primary callback
439+ typeof this . _cb === 'function' && this . _cb ( err , res ) ;
440+ } // end _callback
441+
442+ // Middleware handler
443+ use ( ...args ) {
444+ // Extract routes
445+ let routes =
446+ typeof args [ 0 ] === 'string'
447+ ? Array . of ( args . shift ( ) )
448+ : Array . isArray ( args [ 0 ] )
449+ ? args . shift ( )
450+ : [ '/*' ] ;
451+
452+ // Init middleware stack
453+ let middleware = [ ] ;
454+
455+ // Add func args as middleware
456+ for ( let arg in args ) {
457+ if ( typeof args [ arg ] === 'function' ) {
458+ if ( args [ arg ] . length === 3 ) {
459+ middleware . push ( args [ arg ] ) ;
460+ } else if ( args [ arg ] . length === 4 ) {
461+ this . _errors . push ( args [ arg ] ) ;
462+ } else {
463+ throw new ConfigurationError (
464+ 'Middleware must have 3 or 4 parameters'
465+ ) ;
466+ }
468467 }
469- } // end use
470-
471- // Finally handler
472- finally ( fn ) {
473- this . _finally = fn ;
474468 }
475469
476- //-------------------------------------------------------------------------//
477- // UTILITY FUNCTIONS
478- //-------------------------------------------------------------------------//
479-
480- parseRoute ( path ) {
481- return path
482- . trim ( )
483- . replace ( / ^ \/ ( .* ?) ( \/ ) * $ / , '$1' )
484- . split ( '/' )
485- . filter ( ( x ) => x . trim ( ) !== '' ) ;
470+ // Add middleware for all methods
471+ if ( middleware . length > 0 ) {
472+ routes . forEach ( ( route ) => {
473+ this . METHOD ( '__MW__' , route , ...middleware ) ;
474+ } ) ;
486475 }
476+ } // end use
487477
488- // Load app packages
489- app ( packages ) {
490- // Check for supplied packages
491- if ( typeof packages === 'object' ) {
492- // Loop through and set package namespaces
493- for ( let namespace in packages ) {
494- try {
495- this . _app [ namespace ] = packages [ namespace ] ;
496- } catch ( e ) {
497- console . error ( e . message ) ; // eslint-disable-line no-console
498- }
478+ // Finally handler
479+ finally ( fn ) {
480+ this . _finally = fn ;
481+ }
482+
483+ //-------------------------------------------------------------------------//
484+ // UTILITY FUNCTIONS
485+ //-------------------------------------------------------------------------//
486+
487+ parseRoute ( path ) {
488+ return path
489+ . trim ( )
490+ . replace ( / ^ \/ ( .* ?) ( \/ ) * $ / , '$1' )
491+ . split ( '/' )
492+ . filter ( ( x ) => x . trim ( ) !== '' ) ;
493+ }
494+
495+ // Load app packages
496+ app ( packages ) {
497+ // Check for supplied packages
498+ if ( typeof packages === 'object' ) {
499+ // Loop through and set package namespaces
500+ for ( let namespace in packages ) {
501+ try {
502+ this . _app [ namespace ] = packages [ namespace ] ;
503+ } catch ( e ) {
504+ console . error ( e . message ) ; // eslint-disable-line no-console
499505 }
500- } else if ( arguments . length === 2 && typeof packages === 'string' ) {
501- this . _app [ packages ] = arguments [ 1 ] ;
502- } // end if
506+ }
507+ } else if ( arguments . length === 2 && typeof packages === 'string' ) {
508+ this . _app [ packages ] = arguments [ 1 ] ;
509+ } // end if
503510
504- // Return a reference
505- return this . _app ;
506- }
511+ // Return a reference
512+ return this . _app ;
513+ }
507514
508- // Register routes with options
509- register ( fn , opts ) {
510- let options = typeof opts === 'object' ? opts : { } ;
515+ // Register routes with options
516+ register ( fn , opts ) {
517+ let options = typeof opts === 'object' ? opts : { } ;
511518
512- // Extract Prefix
513- let prefix =
514- options . prefix && options . prefix . toString ( ) . trim ( ) !== ''
515- ? this . parseRoute ( options . prefix )
516- : [ ] ;
519+ // Extract Prefix
520+ let prefix =
521+ options . prefix && options . prefix . toString ( ) . trim ( ) !== ''
522+ ? this . parseRoute ( options . prefix )
523+ : [ ] ;
517524
518- // Concat to existing prefix
519- this . _prefix = this . _prefix . concat ( prefix ) ;
525+ // Concat to existing prefix
526+ this . _prefix = this . _prefix . concat ( prefix ) ;
520527
521- // Execute the routing function
522- fn ( this , options ) ;
528+ // Execute the routing function
529+ fn ( this , options ) ;
523530
524- // Remove the last prefix (if a prefix exists)
525- if ( prefix . length > 0 ) {
526- this . _prefix = this . _prefix . slice ( 0 , - prefix . length ) ;
527- }
528- } // end register
531+ // Remove the last prefix (if a prefix exists)
532+ if ( prefix . length > 0 ) {
533+ this . _prefix = this . _prefix . slice ( 0 , - prefix . length ) ;
534+ }
535+ } // end register
529536
530- // prettyPrint debugger
531- routes ( format ) {
532- // Parse the routes
533- let routes = UTILS . extractRoutes ( this . _routes ) ;
537+ // prettyPrint debugger
538+ routes ( format ) {
539+ // Parse the routes
540+ let routes = UTILS . extractRoutes ( this . _routes ) ;
534541
535- if ( format ) {
536- console . log ( prettyPrint ( routes ) ) ; // eslint-disable-line no-console
537- } else {
538- return routes ;
539- }
542+ if ( format ) {
543+ console . log ( prettyPrint ( routes ) ) ; // eslint-disable-line no-console
544+ } else {
545+ return routes ;
540546 }
547+ }
541548} // end API class
542549
543550// Export the API class as a new instance
0 commit comments