自动try catch路由控制器,使用async await

3

路由器:

  router.get('/available', VehicleController.getAvailable)

  router.put('/:vin/current-location', validate(vehicleValidation.currentLocation), VehicleController.saveCurrentLocation)

控制器

class VehicleController {
  async getAvailable (req, res, next) {
    try {
      res.json(await VehicleQueries.getAvailable())
    } catch (e) {
      next(e)
    }
  }

  async saveCurrentLocation (req, res, next) {
    try {
      res.json(await VehicleQueries.updateLocation(req.params.vin, req.body.lng, req.body.lat))
    } catch (e) {
      next(e)
    }
  }... etc etc

上面是一个简单的 CRUD 应用程序,在使用新的异步和等待功能的 Node.js 中构建。每个路由都会验证输入,然后传递到控制器中。上面的示例调用另一个类中包含查询语句的方法,这些方法会返回一个 Promise。
正如您所看到的,我必须在每个控制器的代码中包含 try 和 catch 代码块 ... 这变得相当烦人,我认为一定有更加简洁的方式。
是否可能以某种方式在控制器方法本身中包装 try catch?这样我就可以将控制器简化为:
class VehicleController {
  async getAvailable (req, res, next) {
      res.json(await VehicleQueries.getAvailable())
  }

  async saveCurrentLocation (req, res, next) {
      res.json(await VehicleQueries.updateLocation(req.params.vin, req.body.lng, req.body.lat))
  }... etc etc
1个回答

0
你可以利用剩余参数展开运算符来构建一个函数来处理try/catch。
async executeQuery(res,next,queryFunction,...queryArguments){
    try {
        res.json(await queryFunction(...queryArguments));
    } catch (e) {
        next(e);
    }
}
async getAvailable (req, res, next) {
    executeQuery(res,next,VehicleQueries.getAvailable);
}

async saveCurrentLocation (req, res, next) {
    executeQuery(res,next,VehicleQueries.updateLocation,req.params.vin, req.body.lng, req.body.lat);
}

是的,但对我来说,这感觉就像我将输出命令传递到应用程序更深的层级,并且现在会相当特定于查询类。如果有一种中间件可以处理捕获异常,那就太好了。某种程度上在路由器级别上实现,路由器先尝试控制器,然后在捕获时调用下一个。而不是将责任传递给控制器,但我无法想出如何实现。 - user1037355
看起来他们有关于错误处理中间件的指南。我尝试制作了一个小应用程序来测试它,但没有成功。你可以试一试,看看它是否适用于你。 - user2033671
是的,我也遇到了同样的问题,但感觉数据流是路由器->操作->错误处理程序。而我想要的解决方案是路由器->尝试操作->捕获错误处理程序。如果我找到答案,我会回复的。谢谢你的帮助。 - user1037355

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接