首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理每个Express路由上的异常

处理每个Express路由上的异常
EN

Stack Overflow用户
提问于 2021-01-15 10:15:58
回答 2查看 116关注 0票数 0

我希望在每个路由上都有一些基本的错误处理,所以如果有异常,API至少会响应500。

根据this pattern的说法,您仍然需要在每条路由中包含一个try/catch块:

代码语言:javascript
复制
app.post('/post', async (req, res, next) => {
  const { title, author } = req.body;
  
  try {
    if (!title || !author) {
      throw new BadRequest('Missing required fields: title or author');
    }
    const post = await db.post.insert({ title, author });
    res.json(post);
  } catch (err) {
    next(err) // passed to the error-handling middleware
  }
});

这看起来有点重复。有没有一种更高级别的方法,可以在任何地方自动捕获异常并将其传递给中间件?

我的意思是,显然我可以定义我自己的appGet()

代码语言:javascript
复制
function appGet(route, cb) {
    app.get(route, async (req, res, next) => {
        try {
          await cb(req, res, next);
        } catch (e) {
            next(e);
        }
    });
}

有没有内置的版本?

EN

回答 2

Stack Overflow用户

发布于 2021-01-15 11:33:52

您可以使用express-promise-router包。

是Express4路由器的一个简单的包装器,它允许中间件返回承诺。这个包通过减少重复代码,使得在处理promises时为Express编写路由处理程序变得更简单。

例如。

app.ts

代码语言:javascript
复制
import express from 'express';
import Router from 'express-promise-router';
import bodyParser from 'body-parser';
const router = Router();
const app = express();
const port = 3000;
app.use(bodyParser.json());
app.use(router);

router.post('/post', async (req, res) => {
  const { title, author } = req.body;
  if (!title || !author) {
    throw new Error('Missing required fields: title or author');
  }
  const post = { title, author };
  res.json(post);
});

router.use((err, req, res, next) => {
  res.status(500).send(err.message);
});

app.listen(port, () => console.log(`Server started at http://localhost:${port}`));

您不再需要try/catch语句块。

测试结果:

票数 1
EN

Stack Overflow用户

发布于 2021-01-15 12:16:58

我认为更好的方法是将服务和控制器分开,如下所示。

添加post服务:

代码语言:javascript
复制
async function addPostService (title, author) => {
    if (!title || !author)
      throw new BadRequest('Missing required fields: title or author');
    
    return await db.post.insert({ title, author });
};

添加post控制器:

代码语言:javascript
复制
function addPost(req, res, next){
    const { title, author }= req.body;

    addPostService
      .then((post) => {
        res.json(post);
      })
      .catch(next) // will go through global error handler middleware
}

现在,我们可以制作一个全局错误处理中间件,它将捕获整个应用程序中任何控制器抛出的错误。

代码语言:javascript
复制
function globalErrorHandler(err, req, res, next){
  switch(true){
    case typeof err === 'string':
      // works for any errors thrown directly
      // eg: throw 'Some error occured!';
      return res.status(404).json({ message: 'Error: Not found!'});
    
    // our custom error
    case err.name = 'BadRequest':
      return res.status(400).json({ message: 'Missing required fields: title or author!'})
    
    default:
      return res.status(500).json({ message: err.message });
  }
}

而且,不要忘记在启动服务器之前使用错误处理中间件。

代码语言:javascript
复制
// ....
app.use(globalErrorHandler);
app.listen(port, () => { console.log('Server started...')});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65729575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档