使用异步/等待时尝试/捕获范围问题

时间:2019-10-23 22:14:57

标签: javascript node.js express mongoose jestjs

我的问题是(看似)事情超出范围,或者当我在下面的函数中输入catch块时,范围被污染了:

export const getOne = model => async (req, res, next) => {
  let id = req.params.id
  let userId = req.user
  try {
    let item = await model.findOne({ _id: id, createdBy: userId }).exec()
    if (!item) {
      throw new Error('Item not found!')
    } else {
      res.status(200).json({ data: item }) // works perfectly
    }
  } catch (e) {
    res.status(400).json({ error: e }) // TypeError: res.status(...).json is not a function
    // also TypeError: next is not a function
    // next(e)
  }
}

足够有趣的是,在res.status(...).end()块中使用catch可以很好地工作,但是令我感到困扰的是我无法将任何详细信息发送回响应。根据{{​​3}}和res.send()的“快速文档”,我应该能够链接到.status(),这也很有趣,在上述try语句中,如果一切都成功了-res.status(200).json(...)运作完美。

我还尝试将错误处理抽象到中间件res.json,并通过闭包,我仍然应该可以在next语句中访问catch,对吗?为什么返回的不是函数?

  1. 为什么res.status(...).json(...)在我的try而不是catch块中起作用?
  2. 为什么next不再是catch块中的函数?

谢谢!

编辑

这在单元测试中失败,以下代码会产生上述错误:

describe('getOne', async () => {
  // this test passes
  test('finds by authenticated user and id', async () => {
    expect.assertions(2)

    const user = mongoose.Types.ObjectId()
    const list = await List.create({ name: 'list', createdBy: user })

    const req = {
      params: {
        id: list._id
      },
      user: {
        _id: user
      }
    }

    const res = {
      status(status) {
        expect(status).toBe(200)
        return this
      },
      json(result) {
        expect(result.data._id.toString()).toBe(list._id.toString())
      }
    }

    await getOne(List)(req, res)
  })
  // this test fails
  test('400 if no doc was found', async () => {
    expect.assertions(2)

    const user = mongoose.Types.ObjectId()

    const req = {
      params: {
        id: mongoose.Types.ObjectId()
      },
      user: {
        _id: user
      }
    }

    const res = {
      status(status) {
        expect(status).toBe(400)
        return this
      },
      end() {
        expect(true).toBe(true)
      }
    }

    await getOne(List)(req, res)
  })
})

1 个答案:

答案 0 :(得分:1)

  

为什么res.status(...)。json(...)可以在我的try中工作但不能捕获块?

似乎您正在传递使用单元测试运行时仅具有statusend方法的非表达对象。这就是为什么它找不到json方法

的原因