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
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
(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?
try removing await next();
@fernandolguevara I have quite a few places where I use it. Which exact part do you suggest to be stripped out?
I have the same issue. @kunokdev were you able to solve this?
@bolein No, not yet, I am still waiting for @fernandolguevara 's response. Meanwhile if it bothers you, do something like this:
process.on("unhandledRejection", e => {
console.error("Rejectable:", e);
});
but this it not a solution, not even a workaround, just a way to not have your errors unhandled.
I think that the issue is in the KoaDriver
@bolein Could you elaborate please?
I found a couple of places in the source code, where setting defaultErrorHandler: false will cause the unhandled promise rejection
That's very unfortunate due to blocked development of this library...
How did you go around it?
I am unsure if defaultErrorHandler being truthy will satisfy my needs since I need custom responses by using my own middleware...
@kunokdev what do you mean by blocked development?
I guess we can fork the repo and fix the issue...
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.
@kunokdev I appreciate your help. Let's make the magic of open-source happen 馃憤
I have same problem, repair if you can please =)
@bolein thre project uses Gulp... I guess I'll have to rewrite build part too. I'll have to make great refactory, it will take a bit more time than just a weekend project. @sicksick ye, we try.
@kunokdev is it really worth it? Or should we all just migrate to nestjs? This project is clearly abandoned
@bolein I think it's not worth it, nestjs seems like good alternative.
And the migration is pretty achievable
Stale issue message
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.