【发布时间】:2016-12-28 07:46:58
【问题描述】:
我正在使用 TypeScript 和 Koa 2 编写应用程序。
但是,我遇到的问题是我的全局 Koa 错误处理程序没有捕获在我的应用程序中引发的错误。
以以下中间件为例(这是加载任何路由之前的第一个中间件):
app.use(async(ctx, next) => {
console.log("ErrorHandler loaded...");
try {
console.log("Trying for error...");
await next();
} catch (err) {
console.log("Caught error...");
ctx.status = err.status || 500;
ctx.response.body = "Error: " + err.message;
}
});
访问我的路由时,我可以看到错误处理程序已加载并且try 块运行。
但是,如果我在路由中抛出错误(无论我使用 throw 还是 ctx.throw),我得到的只是默认错误消息“未找到” - 因此,我抛出的任何错误都不会被捕获因此,我的错误处理程序不会处理它。
现在考虑以下转译的 JavaScript:
app.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
console.log("ErrorHandler loaded...");
try {
console.log("Trying for error...");
yield next();
}
catch (err) {
console.log("Caught error...");
ctx.status = err.status || 500;
ctx.response.body = "Error: " + err.message;
}
}));
问题有两个:
- 我的应用程序是否因为转译而无法捕获抛出的错误?我的意思是,如果转译后的 JavaScript 使用
async和await关键字,而不是使用yield将其转译到生成器,它会起作用吗? - 如果以上正确:现在有没有办法用 TypeScript 编写 Koa 2 应用程序?
编辑
我找到了一个“解决方案”来抛出我的错误,但我仍然不明白为什么 Koa 没有捕捉到它们。
这个for of 循环迭代我动态加载的控制器数组。对于每个控制器,我使用指定的 Http 动词 (action.type) 将类 (action.target) 的相应方法 (action.method) 附加到路由 (action.route)。
但是,我还将上下文绑定到方法,以确保按照 Koa 的约定,this 绑定到 Context:
for (let action of actionMetadata) {
router[action.type.toLowerCase()](action.route, (ctx, next) => {
(new action.target)[action.method].bind(ctx)(ctx, next);
});
}
以上导致错误未被捕获的问题。
相比之下,以下代码有效:错误现在被 Koa 捕获。但这意味着this 现在不再是Context。
我可以忍受,因为 Context 是我的路由中的第一个参数,但我不明白为什么错误没有被捕获,因为错误处理程序(这是我的第一个中间件)之后的所有中间件都应该运行在其try 块内:
for (let action of actionMetadata) {
router[action.type.toLowerCase()](action.route, (new action.target )[action.method]);
}
【问题讨论】:
-
它应该使用转译代码。没有“async 和 await 关键字”,因为该提案尚未标准化且尚未实施。我想 Koa 2 的其他应用程序部分和 beta 状态更有可能受到责备
-
对我来说效果很好。你能展示更多你的代码吗,例如你是如何抛出错误的?中间件的顺序,以及可能有用的东西。
-
您好 - 感谢您的参与。我得到了它的工作,但我仍然认为我以前的实现也应该工作。因此,我为我的问题添加了更新。
-
你为什么要使用类?为什么要在那里创建一个类的实例,而不是从一开始就创建它们,然后只访问实例?然后,如果您不希望实例方法将实例作为
this,那么在类中使用这些函数有什么意义呢? -
至第一点:因为我喜欢使用诸如
@Route("/view/:id", HttpVerb.Get)之类的方法装饰器获得的结构。最后一点:没有意义 - 这是我试图遵循 Koa 约定的纯粹遗物。this。就像我说的:ctx 是第一个参数,我不需要this作为上下文。除了设计选择之外,我想我只是很难理解为什么第一个设置没有捕获抛出的异常,因为没有额外的trys 可能会吞噬它们。
标签: typescript error-handling async-await koa ecmascript-2016