javascript - 我应该避免在 Node js 上的每一个异步/等待中 try catch 吗?

标签 javascript node.js async-await jestjs

这是我在单元测试时遇到的一个设计问题。
让我们深入研究这个例子:
想象一下:

async function foo() {
    try {
        return apiCall()
    }
    catch (e) {
        throw new CustomError(e);
    } 
}



async function bar() {
    return foo()
}



async function main() {
    try {
        await bar()
    }catch(e) {
        console.error(e)
    }
}

main()
我们在这里看到了什么?唯一没有 try-catch block 的函数是 bar。
但是如果 foo 失败了,它应该被 main catch 捕获。
虽然像这样进行单元测试
describe('testing bar', () => {
    it('foo should throw', () => {
        foo.mockImplementantion(() => { throw new CustomError('error')});
        bar()
        .then((result) => console.log(result))
        .catch((err) => { exepect(err).toBeInstanceOf(CustomError)}) // this is what we are testing
    })
})
我们看到的输出是 未处理的 promise 拒绝 已登录控制台。
所以,我的问题是……即使我知道 main()会捕获错误,我应该在所有异步函数中使用 try-catch block 吗?

最佳答案

try..catch如果一个函数能够从错误中恢复,产生像日志记录这样的副作用,或者重新抛出一个更有意义的错误,则可能是必要的。
如果 CustomErrorapiCall 的错误更可取可以扔了try..catch必要的,否则没有。还有 foo 的问题是它只处理同步错误。为了处理被拒绝的 promise ,它应该是 return await apiCall() ,这是 async 的已知陷阱.
未捕获的拒绝是不需要的,它们目前导致 UnhandledPromiseRejectionWarning并且预计在 future 的版本中会导致 Node 崩溃。最好在顶层以有意义的方式处理错误,所以 main需要捕捉错误。这可以委托(delegate)给 process uncaughtRejection事件处理程序,但它可能有益于保持永远不会达到的额外错误处理级别。

The output we see is that an Unhandled promise rejection is logged in the console.


这不应该发生。拒绝需要由测试处理。上面解释了一种可能的故障点,foo可以从 apiCall 返回原始错误而不是 CustomError万一它没有被正确地模拟,这将不符合预期并导致 catch() 中未处理的拒绝。 .另一个失败点是测试具有未链接的 promise ,因为它没有被返回,测试总是通过。
使用 Promise 的异步测试应该总是返回一个 Promise。这可以通过使用 async..await 来改善。 . fooasync ,它应该总是返回一个 promise :
it('foo should throw', async () => {
    foo.mockImplementantion(() => { return Promise.reject(new CustomError('error')) });
    await expect(bar()).rejects.toThrow(CustomError);
})
现在就算foo模拟失败(foo 模拟不会影响 bar 如果它们被定义在同一个模块中,如图所示)和 bar拒绝 CustomError 以外的东西,这将被断言。

关于javascript - 我应该避免在 Node js 上的每一个异步/等待中 try catch 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63251622/

相关文章:

javascript - 使用 React JS 的 HandleClick 不使用绑定(bind)

javascript - 在 A 框架中,如何通过光线转换器相交事件更改实体的属性?

javascript - 从 github 执行示例时,Uglify JS API 抛出 TypeError

node.js - Mongo 每天汇总 $group 吗?

javascript - JsTree 多树cookie

javascript - JS Regex匹配大括号内的所有内容(包括嵌套大括号): "{ I want this {and this} and this in one string }"

javascript - 如何通过 Node.js 或 NPM 模块组合/序列化此类 JSON 对象?

c# - 是否有机会将 "wrap"这个 native iOS API 调用转换为异步/等待?

python - 为什么我不能在异步函数中使用 'yield from'?

async-await - Dart:如何管理异步函数中的并发