使用async/await时try/catch中的作用域出现问题



当我在下面的函数中输入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)
}
}

有趣的是,在catch块中使用res.status(...).end()工作得很好,但我无法将任何细节与响应一起发送回来,这让我很困扰。根据res.send()res.json的Express Documentation,我应该能够连锁.status(),同样有趣的是,如果事情成功的话,它在上面的try语句中运行得很好——res.status(200).json(...)运行得很完美。

此外,正如Express文档中所建议的,我尝试将错误处理抽象到中间件,通过闭包,我应该仍然可以访问catch语句中的next,对吧?为什么这不是一个函数?

  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)
})
})

为什么res.status(…(.json(…(在我的try块中有效,但在catch块中无效?

似乎您正在传递一个只有status&end方法在运行时使用单元测试。这就是为什么它找不到json方法

最新更新