11import { format } from 'url'
22import { Request , Response } from 'servie'
3- import { STATUS_CODES } from 'http'
3+ import { errorhandler } from 'servie-errorhandler'
4+ import { finalhandler } from 'servie-finalhandler'
45
56export type App = ( req : Request , next : ( ) => Promise < Response > ) => Promise < Response >
67
@@ -70,8 +71,7 @@ export function createHandler (fn: App, options: Options = {}) {
7071 const { httpMethod : method , headers, isBase64Encoded } = event
7172 const url = format ( { pathname : event . path , query : event . queryStringParameters } )
7273 const body = event . body ? new Buffer ( event . body , isBase64Encoded ? 'base64' : 'utf8' ) : undefined
73- const logError = options . logError || ( ( err : Error ) => console . error ( err ) )
74- const production = options . production == null ? ( process . env [ 'NODE_ENV' ] === 'production' ) : options . production
74+ const isBinary = options . isBinary || ( ( ) => false )
7575 let returned = false
7676
7777 const connection = {
@@ -81,82 +81,56 @@ export function createHandler (fn: App, options: Options = {}) {
8181
8282 const req = new Request ( { method, url, connection, headers, body } )
8383
84- // Handle request and response errors.
85- req . events . on ( 'error' , done )
86- req . events . on ( 'abort' , ( ) => done ( null , { statusCode : 444 } ) )
87-
88- // Marked request as finished.
89- req . started = true
90- req . finished = true
91- req . bytesTransferred = body ? body . length : 0
92-
93- function done ( err : Error | null , res ?: Result ) {
94- returned = true
84+ const mapError = errorhandler ( req , {
85+ log : options . logError ,
86+ production : options . production
87+ } )
9588
96- if ( err ) {
97- logError ( err )
89+ function sendError ( err : Error ) {
90+ return sendResponse ( mapError ( err ) )
91+ }
9892
99- return cb ( null , mapError ( err , production ) )
93+ function sendResponse ( res : Response ) : Promise < void > {
94+ if ( returned ) {
95+ return Promise . resolve ( )
10096 }
10197
102- return cb ( null , res )
103- }
104-
105- fn ( req , finalhandler ( req ) )
106- . then ( ( res ) : void | Promise < void > => {
107- if ( returned ) {
108- return
109- }
98+ res . started = true
99+ req . events . emit ( 'response' , res )
110100
111- // Mark the response as started.
112- res . started = true
113- req . events . emit ( 'response' , res )
101+ return res . buffer ( )
102+ . then ( ( body ) => {
103+ const isBase64Encoded = isBinary ( res )
114104
115- return res . buffer ( ) . then ( ( body ) => {
116- const isBase64Encoded = options . isBinary ? options . isBinary ( res ) : false
105+ returned = true
117106
118107 // Mark the response as finished when buffering is done.
119108 res . finished = true
120109 res . bytesTransferred = body ? body . length : 0
121110
122- return done ( null , {
111+ return cb ( null , {
123112 statusCode : res . status ,
124113 body : body ? ( isBase64Encoded ? body . toString ( 'base64' ) : body . toString ( 'utf8' ) ) : undefined ,
125114 headers : res . headers . object ( ) ,
126115 isBase64Encoded
127116 } )
128117 } )
129- } )
130- . catch ( ( err ) => done ( err ) )
131- }
132- }
118+ . catch ( ( err ) => sendError ( err ) )
119+ }
133120
134- /**
135- * Map a request error to lambda.
136- */
137- function mapError ( err : any , production : boolean ) : Result {
138- const status = err . status || 500
139- const body = ( production ? STATUS_CODES [ status ] : ( err . stack || String ( err ) ) ) || ''
140-
141- return {
142- statusCode : status ,
143- headers : {
144- 'content-type' : 'text/plain' ,
145- 'content-length' : String ( Buffer . byteLength ( body ) )
146- } ,
147- body : body ,
148- isBase64Encoded : false
149- }
150- }
121+ // Handle request and response errors.
122+ req . events . on ( 'error' , ( err : Error ) => sendError ( err ) )
123+ req . events . on ( 'abort' , ( ) => sendResponse ( new Response ( { status : 444 } ) ) )
151124
152- /**
153- * Final throwback server handler.
154- */
155- function finalhandler ( req : Request ) {
156- return function ( ) {
157- return Promise . resolve ( new Response ( {
158- status : 404 ,
159- body : `Cannot ${ req . method } ${ req . url } `
160- } ) )
125+ // Marked request as finished.
126+ req . started = true
127+ req . finished = true
128+ req . bytesTransferred = body ? body . length : 0
129+
130+ fn ( req , finalhandler ( req ) )
131+ . then (
132+ ( res ) => sendResponse ( res ) ,
133+ ( err ) => sendError ( err )
134+ )
161135 }
162136}
0 commit comments