节点 8.1.2,我有一个结构,其中一个文件在映射中调用另一个文件的函数。在一个真实的例子中我会使用Promise.all
on the map
但这不是这里的问题。结构如下:
A.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
return b(thing)
}))
return res.status(200).json(...)
}
B.js:
// Thing -> Promise<Object>
function b (thing) {
return ThingModel.update(...) // this returns a Promise but FAILS and throws an errror
}
module.exports = { b }
好的。所以在功能上b
我尝试获取一些异步数据(从数据库)。它失败并抛出 Uncaught Promise Rejection。
该如何应对呢?
我尝试了多种解决方案:
A1.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
try {
return b(thing)
} catch (err) {
return next(err)
}
}))
return res.status(200).json(...)
}
但这仍然没有被捕获。
A2.js
:
const { b } = require('./B')
function expressStuff (req, res, next) {
try {
things.map(thing => {
return b(thing)
}))
} catch (err) {
return next(err)
}
return res.status(200).json(...)
}
仍然没有处理。我尝试使用Promise.all
,我尝试了双 try-catch 块(因为我认为里面的那个map
可能会回来next
从 到map
结果而不是实际上来自expressStuff
功能。依然没有。
我得到答案的最后是处理错误,但代码不会等待它被抛出,并且两者res.status()
and next
将导致竞争条件和cannot set headers after they are sent
errors.
我想做的只是为了功能b
抛出错误但将其捕获在expressStuff
这样我就可以重新抛出自定义UnprocessableEntityError
并将其传递给next
。看起来像是文件中的错误B
没有冒泡到map
它被称为哪里。
我该怎么做?
EDIT:
我处理这个拒绝的唯一方法就是尝试在B.js
。但如果我尝试重新抛出错误/返回它 - 什么也没有。错误被吞噬。如果我尝试console.log
它 - 但它会被记录。
DETAILS:
感谢标记的答案,我重构了我的实际代码并使其完美工作。
function expressStuff (res, req, next) {
try {
await Promise.all(things.map(async thing => {
if (ifSomething()) {
await b(thing)
}
}))
} catch (err) {
return next(new MyCustomError('My Custom Error Message'))
}
return res.status(200).json(...)
}