@@ -18,6 +18,9 @@ import * as supertest from 'supertest';
1818
1919import * as functions from '../../src/index' ;
2020import { getTestServer } from '../../src/testing' ;
21+ import { Request , Response , NextFunction } from 'express' ;
22+ import * as express from 'express' ;
23+ import { getServer } from '../../src/server' ;
2124
2225describe ( 'HTTP Function' , ( ) => {
2326 let callCount = 0 ;
@@ -111,4 +114,88 @@ describe('HTTP Function', () => {
111114 assert . strictEqual ( callCount , test . expectedCallCount ) ;
112115 } ) ;
113116 } ) ;
117+
118+ it ( 'default error handler' , async ( ) => {
119+ const app = express ( ) ;
120+ app . post ( '/foo' , async ( req , res ) => {
121+ res . send ( 'Foo!' ) ;
122+ } ) ;
123+ app . use (
124+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
125+ ( _err : Error , _req : Request , res : Response , _next : NextFunction ) => {
126+ res . status ( 500 ) . send ( 'Caught error!' ) ;
127+ }
128+ ) ;
129+ functions . http ( 'testHttpFunction' , app ) ;
130+ const malformedBody = '{"key": "value", "anotherKey": }' ;
131+ const st = supertest (
132+ getServer ( app , {
133+ port : '' ,
134+ target : '' ,
135+ sourceLocation : '' ,
136+ signatureType : 'http' ,
137+ printHelp : false ,
138+ enableExecutionId : false ,
139+ timeoutMilliseconds : 0 ,
140+ ignoredRoutes : null ,
141+ propagateFrameworkErrors : false ,
142+ } )
143+ ) ;
144+ const resBody =
145+ '<!DOCTYPE html>\n' +
146+ '<html lang="en">\n' +
147+ '<head>\n' +
148+ '<meta charset="utf-8">\n' +
149+ '<title>Error</title>\n' +
150+ '</head>\n' +
151+ '<body>\n' +
152+ '<pre>SyntaxError: Unexpected token '}', ..."therKey": }" is not valid JSON<br> at JSON.parse (<anonymous>)<br> at parse (/Users/gregei/IdeaProjects/functions-framework-nodejs/node_modules/body-parser/lib/types/json.js:92:19)<br> at /Users/gregei/IdeaProjects/functions-framework-nodejs/node_modules/body-parser/lib/read.js:128:18<br> at AsyncResource.runInAsyncScope (node:async_hooks:211:14)<br> at invokeCallback (/Users/gregei/IdeaProjects/functions-framework-nodejs/node_modules/raw-body/index.js:238:16)<br> at done (/Users/gregei/IdeaProjects/functions-framework-nodejs/node_modules/raw-body/index.js:227:7)<br> at IncomingMessage.onEnd (/Users/gregei/IdeaProjects/functions-framework-nodejs/node_modules/raw-body/index.js:287:7)<br> at IncomingMessage.emit (node:events:518:28)<br> at IncomingMessage.emit (node:domain:552:15)<br> at endReadableNT (node:internal/streams/readable:1698:12)<br> at process.processTicksAndRejections (node:internal/process/task_queues:90:21)</pre>\n' +
153+ '</body>\n' +
154+ '</html>\n' ;
155+
156+ const response = await st
157+ . post ( '/foo' )
158+ . set ( 'Content-Type' , 'application/json' )
159+ . send ( malformedBody ) ;
160+
161+ assert . strictEqual ( response . status , 400 ) ;
162+ assert . equal ( response . text , resBody ) ;
163+ } ) ;
164+
165+ it ( 'user application error handler' , async ( ) => {
166+ const app = express ( ) ;
167+ const resBody = 'Caught error!' ;
168+ app . post ( '/foo' , async ( req , res ) => {
169+ res . send ( 'Foo!' ) ;
170+ } ) ;
171+ app . use (
172+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
173+ ( _err : Error , _req : Request , res : Response , _next : NextFunction ) => {
174+ res . status ( 500 ) . send ( resBody ) ;
175+ }
176+ ) ;
177+ functions . http ( 'testHttpFunction' , app ) ;
178+ const malformedBody = '{"key": "value", "anotherKey": }' ;
179+ const st = supertest (
180+ getServer ( app , {
181+ port : '' ,
182+ target : '' ,
183+ sourceLocation : '' ,
184+ signatureType : 'http' ,
185+ printHelp : false ,
186+ enableExecutionId : false ,
187+ timeoutMilliseconds : 0 ,
188+ ignoredRoutes : null ,
189+ propagateFrameworkErrors : true ,
190+ } )
191+ ) ;
192+
193+ const response = await st
194+ . post ( '/foo' )
195+ . set ( 'Content-Type' , 'application/json' )
196+ . send ( malformedBody ) ;
197+
198+ assert . strictEqual ( response . status , 500 ) ;
199+ assert . equal ( response . text , resBody ) ;
200+ } ) ;
114201} ) ;
0 commit comments