Node.js 处理每条快线上的例外情况

Node.js 处理每条快线上的例外情况,node.js,express,error-handling,middleware,Node.js,Express,Error Handling,Middleware,我希望每个路由上都有一些基本的错误处理,因此如果有异常,API至少会响应500次 根据,您仍然需要在每条路线中包含try/catch块: app.post('/post', async (req, res, next) => { const { title, author } = req.body; try { if (!title || !author) { throw new BadRequest('Missing required fields: t

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

根据,您仍然需要在每条路线中包含
try/catch
块:

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

是否有此软件包的内置版本?

您可以使用此软件包

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

例如

app.ts

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
语句块

测试结果:

您可以使用软件包

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

例如

app.ts

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
语句块

测试结果:


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

增加邮政服务:

async function addPostService (title, author) => {
    if (!title || !author)
      throw new BadRequest('Missing required fields: title or author');
    
    return await db.post.insert({ title, author });
};
添加邮政管理员:

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
}
现在,我们可以制作一个全局错误处理程序中间件,它将捕获整个应用程序中任何控制器抛出的错误

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 });
  }
}
而且,不要忘记在启动服务器之前使用错误处理程序中间件

// ....
app.use(globalErrorHandler);
app.listen(port, () => { console.log('Server started...')});

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

增加邮政服务:

async function addPostService (title, author) => {
    if (!title || !author)
      throw new BadRequest('Missing required fields: title or author');
    
    return await db.post.insert({ title, author });
};
添加邮政管理员:

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
}
现在,我们可以制作一个全局错误处理程序中间件,它将捕获整个应用程序中任何控制器抛出的错误

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 });
  }
}
而且,不要忘记在启动服务器之前使用错误处理程序中间件

// ....
app.use(globalErrorHandler);
app.listen(port, () => { console.log('Server started...')});

嗯,有用的想法,谢谢。它仍然在每个路由中都包含一个异常处理程序(这里稍微伪装成
.catch(…)
),但实际上,如果您想到它,就没有其他方法了。显然,根据业务需求,每个路由都涉及错误处理。处理错误有两种选择:一种是使用async await尝试catch,或者返回承诺并使用.catch().Hmm,有用的想法,谢谢。它仍然在每个路由中都包含一个异常处理程序(这里稍微伪装成
.catch(…)
),但实际上,如果您想到它,就没有其他方法了。显然,根据业务需求,每个路由都涉及错误处理。处理错误有两种选择:一种是使用async await尝试catch,或者返回承诺并使用.catch()。