@@ -13,6 +13,7 @@ import {isPromiseLike} from "../../util/isPromiseLike";
13
13
import { getFromContainer } from "../../container" ;
14
14
import { RoleChecker } from "../../RoleChecker" ;
15
15
import { AuthorizationRequiredError } from "../../error/AuthorizationRequiredError" ;
16
+ import { NotFoundError , HttpError } from "../../index" ;
16
17
const cookie = require ( "cookie" ) ;
17
18
const templateUrl = require ( "template-url" ) ;
18
19
@@ -215,18 +216,13 @@ export class KoaDriver extends BaseDriver implements Driver {
215
216
}
216
217
217
218
// set http status code
218
- if ( action . undefinedResultCode && result === undefined ) {
219
- if ( action . undefinedResultCode instanceof Function )
220
- throw new ( action . undefinedResultCode as any ) ( options ) ;
221
-
222
- options . response . status = action . undefinedResultCode ;
223
-
224
- } else if ( action . nullResultCode && result === null ) {
225
- if ( action . nullResultCode instanceof Function )
219
+ if ( result === undefined && action . undefinedResultCode && action . undefinedResultCode instanceof Function ) {
220
+ throw new ( action . undefinedResultCode as any ) ( options ) ;
221
+ }
222
+ else if ( result === null && action . nullResultCode ) {
223
+ if ( action . nullResultCode instanceof Function ) {
226
224
throw new ( action . nullResultCode as any ) ( options ) ;
227
-
228
- options . response . status = action . nullResultCode ;
229
-
225
+ }
230
226
} else if ( action . successHttpCode ) {
231
227
options . response . status = action . successHttpCode ;
232
228
}
@@ -247,81 +243,81 @@ export class KoaDriver extends BaseDriver implements Driver {
247
243
248
244
return options . next ( ) ;
249
245
250
- } else if ( action . renderedTemplate ) { // if template is set then render it // todo : not working in koa
246
+ } else if ( action . renderedTemplate ) { // if template is set then render it // TODO : not working in koa
251
247
const renderOptions = result && result instanceof Object ? result : { } ;
252
248
253
249
this . koa . use ( async function ( ctx : any , next : any ) {
254
250
await ctx . render ( action . renderedTemplate , renderOptions ) ;
255
251
} ) ;
256
252
257
253
return options . next ( ) ;
258
-
259
- } else if ( result !== undefined || action . undefinedResultCode ) { // send regular result
260
- if ( result === null || ( result === undefined && action . undefinedResultCode ) ) {
261
-
262
- if ( action . isJsonTyped ) {
263
- options . response . body = null ;
264
- } else {
265
- options . response . body = null ;
266
- }
267
-
268
- // todo: duplication. we make it here because after we set null to body koa seems overrides status
269
- if ( action . nullResultCode ) {
270
- options . response . status = action . nullResultCode ;
271
-
272
- } else if ( result === undefined && action . undefinedResultCode ) {
273
- options . response . status = action . undefinedResultCode ;
274
- }
275
-
276
- return options . next ( ) ;
254
+ }
255
+ else if ( result === undefined ) { // throw NotFoundError on undefined response
256
+ const notFoundError = new NotFoundError ( ) ;
257
+ if ( action . undefinedResultCode ) {
258
+ notFoundError . httpCode = action . undefinedResultCode as number ;
259
+ }
260
+ throw notFoundError ;
261
+ }
262
+ else if ( result === null ) { // send null response
263
+ if ( action . isJsonTyped ) {
264
+ options . response . body = null ;
277
265
} else {
278
- if ( result instanceof Object ) {
279
- options . response . body = result ;
280
- } else {
281
- options . response . body = result ;
282
- }
283
- return options . next ( ) ;
266
+ options . response . body = null ;
267
+ }
268
+
269
+ // Setting `null` as a `response.body` means to koa that there is no content to return
270
+ // so we must reset the status codes here.
271
+ if ( action . nullResultCode ) {
272
+ options . response . status = action . nullResultCode ;
273
+ } else {
274
+ options . response . status = 204 ;
275
+ }
276
+
277
+ return options . next ( ) ;
278
+ }
279
+ else { // send regular result
280
+ if ( result instanceof Object ) {
281
+ options . response . body = result ;
282
+ } else {
283
+ options . response . body = result ;
284
284
}
285
285
286
- } else {
287
286
return options . next ( ) ;
288
287
}
289
288
}
290
289
291
290
/**
292
291
* Handles result of failed executed controller action.
293
292
*/
294
- handleError ( error : any , action : ActionMetadata | undefined , options : Action ) : any {
295
- if ( this . isDefaultErrorHandlingEnabled ) {
296
- const response : any = options . response ;
297
-
298
- // set http status
299
- // note that we can't use error instanceof HttpError properly anymore because of new typescript emit process
300
- if ( error . httpCode ) {
301
- options . context . status = error . httpCode ;
302
- response . status = error . httpCode ;
303
- } else {
304
- options . context . status = 500 ;
305
- response . status = 500 ;
306
- }
293
+ handleError ( error : any , action : ActionMetadata | undefined , options : Action ) {
294
+ return new Promise ( ( resolve , reject ) => {
295
+ if ( this . isDefaultErrorHandlingEnabled ) {
296
+ // set http status
297
+ if ( error instanceof HttpError && error . httpCode ) {
298
+ options . response . status = error . httpCode ;
299
+ } else {
300
+ options . response . status = 500 ;
301
+ }
307
302
308
- // apply http headers
309
- if ( action ) {
310
- Object . keys ( action . headers ) . forEach ( name => {
311
- response . set ( name , action . headers [ name ] ) ;
312
- } ) ;
313
- }
303
+ // apply http headers
304
+ if ( action ) {
305
+ Object . keys ( action . headers ) . forEach ( name => {
306
+ options . response . set ( name , action . headers [ name ] ) ;
307
+ } ) ;
308
+ }
314
309
315
- // send error content
316
- if ( action && action . isJsonTyped ) {
317
- response . body = this . processJsonError ( error ) ;
318
- } else {
319
- response . body = this . processJsonError ( error ) ;
320
- }
310
+ // send error content
311
+ if ( action && action . isJsonTyped ) {
312
+ options . response . body = this . processJsonError ( error ) ;
313
+ } else {
314
+ options . response . body = this . processTextError ( error ) ;
315
+ }
321
316
322
- return Promise . resolve ( ) ;
323
- }
324
- return Promise . reject ( error ) ;
317
+ return resolve ( ) ;
318
+ }
319
+ return reject ( error ) ;
320
+ } ) ;
325
321
}
326
322
327
323
// -------------------------------------------------------------------------
0 commit comments