我的代码由路由、全局错误处理程序和一个验证函数组成。 代码的第一个版本是完全同步的,一切正常。现在我正在尝试将其设为异步,因此验证函数如下所示:
const validateGenres = async (genres) => {
const fromDB = await genre.find(); // code here is fine, it always find genres
const validationArr = genres.reduce((acc, e) => {
...code
}, [])
if (validationArr.length !== 0) {
throw new ValidationError(`Missing genres ${validationArr}`); //this error causes UnhandledPromiseRejectionWarning
}
return genres;
}
为了捕获所有错误,我创建了全局错误处理程序:
async function errorHandler(err, req, res, next) {
logger.log({ message: err, level: 'error' });
if (err instanceof CustomError) {
return res.status(err.statusCode).send({ errors: err.serializeErrors() });
}
res.status(400).send({
errors: [{ message: 'Something went wrong' }]
});
}
问题是,现在每当抛出新的 ValidationError 时,它都不会执行 errorHandler 而是会抛出:
(node:11253) UnhandledPromiseRejectionWarning: Error
at validateGenres (/home/mat/Projects/-task-v3/-task-v3/src/middlewares/schema-validator.js:16:15)
at async /home/mat/Projects/-task-v3/-task-v3/src/routes/findAll.js:19:28
findAll 基本上是路由器端点,看起来像:
router.get('/api/movies/findAll/:runtime?/:genres?', async (req, res) => {
movies = await movie.find(params);
res.status(200).json(movies)
})
更重要的是,注册全局错误处理程序我已经这样做了:
const app = express();
app.use(json());
app.use(findAllRouter);
app.use(createRouter);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.all('*', async (req, res) => {
res.status(404).json({ "errors": [ { "message": "No such endpoint" } ] })
});
app.use(errorHandler);
const start = () => app.listen(PORT, () => { console.log(`Listening on port ${PORT}`) });
module.exports = { start }
答案 0 :(得分:1)
在 express 中使用 foreach (PSObject obj in results) {
foreach (PSPropertyInfo objProperties in obj.Properties) {
string pName = objProperties.Name.ToString(); // returns "IPAddress"
**string pValue = objProperties.Value.ToString(); // returns "System.String[]" and not an actual IP address**
}
}
函数作为中间件回调时要小心。
Express 不会在 async
回调函数中捕获您未捕获的异常,您将获得 async
。
如果您想要 UnhandledPromiseRejectionWarning
回调,您可以执行以下操作:
async
也为您的 // Declare on this wrapper function
function callbackWrap(fn) {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
}
// And use it in your code
router.get('/api/movies/findAll/:runtime?/:genres?', callbackWrap(async (req, res) => {
movies = await movie.find(params);
res.status(200).json(movies)
}))
执行此操作(尽管如果不需要 errorHandler
,最好将其删除)