UnhandledPromiseRejectionWarning:抛出错误时出错

时间:2021-03-20 18:04:07

标签: node.js async-await

我的代码由路由、全局错误处理程序和一个验证函数组成。 代码的第一个版本是完全同步的,一切正常。现在我正在尝试将其设为异步,因此验证函数如下所示:

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 }

1 个答案:

答案 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,最好将其删除)