routing-controllers: Unhandled promise rejection after last middleware

Even tho I handle all errors in last middleware, they get thrown and unhandled afterwards. I am using Koa.

This is the way I initialize routing-controllers:

private init(): void {
    try {
      this.server = createKoaServer({
        controllers: [__dirname + "/components/*/controller.ts"],
        middlewares: [errorHandler, logger, successResponseWrapper],
        defaultErrorHandler: false
      });
    } catch (e) {
      throw e;
    }
  }

This is my sample controller method:

@Controller("/tags")
export class TagsController {
  @Post("/")
  @UseBefore(validateRequest(creationSchema))
  async createTag(@Body() body: ITag): Promise<string> {
    if (await new Tag(body).create()) return "Successfully created new tag";
    throw new AlreadyExists("Tag with given name already exists");
  }
  ...

This is my HOF middleware:

export default (schema: joi.SchemaLike) => {
  @Middleware({ type: "before" })
  class RequestValidator implements KoaMiddlewareInterface {
    public async use(ctx: Context, next: Function) {
      try {
        const result = joi.validate(ctx.request.body, schema);
        if (result.error) throw new ValidationFailed(result.error.message);
        return await next();
      } catch (e) {
        throw e;
      }
    }
  }
  return RequestValidator;
};

This is my error handling middleware:


@Middleware({ type: "before" })
export default class ErrorHandler implements KoaMiddlewareInterface {
  public async use(ctx: Context, next: Function) {
    try {
      await next();
    } catch (err) {
      // log
      console.log("ERR:", err);
      if (err.httpCode && err.httpCode < 500)
        return handleClientError({
          ctx,
          message: err.message,
          status: err.httpCode
        });

      if (err.name === "ValidationError")
        return handleClientError({
          ctx,
          message: err.message,
          status: 400
        });

      return handleServerError({ ctx, message: "Internal server error" });
    }
  }
}

This is my response handler:

export function handleClientError({ ctx, message, status }: IParam): Context {
  ctx.status = status || 400;
  ctx.body = {
    message,
    success: false
  };
  return ctx;
}

and this is thrown error:

export class ValidationFailed extends HttpError {
  constructor(message: string = "Validation failed") {
    super(422, message);
  }
}

Even tho response is working well as expected, somehow somewhere error when through after error handler and was not handled. As you can see in output below, middleware logged error, and then after it Unhandled promise rejection expception is shown.

ERR: { Error at new HttpError (/Users/kuno/code/backend-freelancer-tool/src/http-error/HttpError.ts:19:22) at new ValidationFailed (/Users/kuno/code/backend-freelancer-tool/src/utils/responseConstructs.ts:47:5) at RequestValidator.use (/Users/kuno/code/backend-freelancer-tool/src/middlewares/validateRequest.ts:13:33) at /Users/kuno/code/backend-freelancer-tool/src/driver/koa/KoaDriver.ts:333:104 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:44:32) at next (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:45:18) at /Users/kuno/code/backend-freelancer-tool/node_modules/koa-router/lib/router.js:346:16 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:44:32) at /Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:36:12 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-router/lib/router.js:351:31) at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa/node_modules/koa-compose/index.js:42:32) at ErrorHandler.use (/Users/kuno/code/backend-freelancer-tool/src/middlewares/errorHandler.ts:9:13) at /Users/kuno/code/backend-freelancer-tool/src/driver/koa/KoaDriver.ts:61:72 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa/node_modules/koa-compose/index.js:42:32) at bodyParser (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-bodyparser/index.js:86:11) at <anonymous> httpCode: 422, message: ‘child “content” fails because [“content” is required]’ } (node:30035) UnhandledPromiseRejectionWarning: Error at new HttpError (/Users/kuno/code/backend-freelancer-tool/src/http-error/HttpError.ts:19:22) at new ValidationFailed (/Users/kuno/code/backend-freelancer-tool/src/utils/responseConstructs.ts:47:5) at RequestValidator.use (/Users/kuno/code/backend-freelancer-tool/src/middlewares/validateRequest.ts:13:33) at /Users/kuno/code/backend-freelancer-tool/src/driver/koa/KoaDriver.ts:333:104 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:44:32) at next (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:45:18) at /Users/kuno/code/backend-freelancer-tool/node_modules/koa-router/lib/router.js:346:16 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:44:32) at /Users/kuno/code/backend-freelancer-tool/node_modules/koa-compose/index.js:36:12 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-router/lib/router.js:351:31) at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa/node_modules/koa-compose/index.js:42:32) at ErrorHandler.use (/Users/kuno/code/backend-freelancer-tool/src/middlewares/errorHandler.ts:9:13) at /Users/kuno/code/backend-freelancer-tool/src/driver/koa/KoaDriver.ts:61:72 at dispatch (/Users/kuno/code/backend-freelancer-tool/node_modules/koa/node_modules/koa-compose/index.js:42:32) at bodyParser (/Users/kuno/code/backend-freelancer-tool/node_modules/koa-bodyparser/index.js:86:11) at <anonymous> (node:30035) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3) (node:30035) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Response is as expected:

{
    "message": "child \"content\" fails because [\"content\" is required]",
    "success": false
}

Have I missed something?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 19

Most upvoted comments

I have same problem, repair if you can please =)

Thanks for these points, I will take a deeper look into the implementation of KoaDriver & fork it over the weekend. Will notify you of my progress.

If you have time, I’d fork the library, set up a testing environment and look into the Koa driver. Especially, I would pay attention to this and this invocations, as they will both cause the UnhandledRejectionWarning when called with defaultErrorHandler set to false.

@kunokdev what do you mean by blocked development? I guess we can fork the repo and fix the issue…