处理ExpressJS中混合的同步和异步错误的最佳方法

时间:2018-11-29 15:46:05

标签: node.js typescript express error-handling braintree

使用NodeJS 10.13.0,ExpressJS 4.16.4 ... 有一个控制器处理如下所示的路由:

import { Request, Response, NextFunction } from 'express';
import braintree from 'braintree';
import config from '../../server.config';

export function index(req: Request, res: Response, next: NextFunction): void {
  if(!config.braintree) throw new Error('Braintree configuration missing.');
  const gateway: any = braintree.connect(config.braintree); // synchronous
  return gateway.clientToken.generate({})
    .then(response => res.send(response.clientToken))
    .catch(next) // operational error unless config.braintree was changed
}

在阅读ExpressJS docs on error handling时,我想知道我是否遵循最佳实践-为同步部分抛出错误,并将错误传递给异步部分的catch中的next()。

有什么改进建议吗?

1 个答案:

答案 0 :(得分:0)

考虑到使用了承诺,可以使用async函数来一致地处理同步和异步错误:

export async function index(req: Request, res: Response, next: NextFunction) {
  try {
    if(!config.braintree)
      throw new Error('Braintree configuration missing.');

    const gateway: any = braintree.connect(config.braintree);
    const response = await gateway.clientToken.generate({})
    res.send(response.clientToken);
  } catch (err) {
    next(err);
  }
}

由于Express不支持Promise,因此async函数主体应使用try..catch包装。考虑到try..catch对于所有async中间件功能都是通用的,因此可以将其移至辅助程序:

const asyncMiddleware = (middleware: RequestHandler) => async (req: Request, res: Response, next: NextFunction) => {
  try {
    await middleware(req, res, next);
  } catch (err) {
    next(err)
  }
};

其用法类似于:

export const index = asyncMiddleware(async (...) => {...});