TypeScript 和 Koa 2 : async/await issue with Global Error Handler

标签 typescript error-handling async-await koa ecmascript-2016

我正在使用 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 block 正在运行。

但是,如果我在路由中抛出错误(无论我使用 throw 还是 ctx.throw),我得到的只是默认错误消息“Not找到”- 因此,我抛出的任何错误都不会被捕获,因此,我的错误处理程序不会处理它。

现在考虑以下转译的 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;
    }
}));

问题有两个方面:

  1. 我的应用程序是否因为转译而无法捕获抛出的错误?我的意思是,如果转译的 JavaScript 使用 asyncawait 关键字,而不是使用 yield 将其转译为生成器,它会起作用吗?
  2. 如果以上是正确的:现在有没有办法用 TypeScript 编写 Koa 2 应用程序?

编辑

我找到了一个“解决方案”来抛出我的错误,但我仍然不明白为什么 Koa 没有捕捉到它们。

这个 for of 循环迭代我动态加载的 Controller 数组。对于每个 Controller ,我使用指定的 Http 动词 (action.type) 将类 (action.target) 的相应方法 (action.method) 附加到路由 (action.route)。

但是,我还将上下文绑定(bind)到方法,以确保按照 Koa 的约定,this 绑定(bind)到 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 block 中运行:

for (let action of actionMetadata) {
    router[action.type.toLowerCase()](action.route, (new action.target )[action.method]);
}

最佳答案

是的,看起来这是纯粹的用户错误,没有确保每个中间件都返回一个 promise(或者是一个异步函数)。

下面的 async 就是所缺少的:

for (let action of actionMetadata) {
    router[action.type.toLowerCase()](action.route, async (ctx, next) => {
        (new action.target)[action.method].bind(ctx)(ctx, next);
    });
}

关于TypeScript 和 Koa 2 : async/await issue with Global Error Handler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39068002/

相关文章:

c# - 如何在 C# 中调用 async void 事件处理程序?

typescript - RxJS - 每 3 秒查询一次服务器,持续 15 秒或正结果

javascript - 如何从 Nest.js 中的服务触发应用程序关闭?

javascript - QuillJS 选择更改出于某种原因缓存结果

python-3.x - Python-错误检查

c# - 如何获取异步 Task<string> 方法 name() 的返回值?

typescript - TS 索引类型 - 在接口(interface)中使用索引类型时,编译器无法解析精确值

c++ - 我在C++程序中遇到bad_alloc错误

python - 如何区分 ValueError 的情况

c# - 在同步方法中使用 Task.Run() 以避免死锁等待异步方法?