在 ExpressJS 中处理混合同步和异步错误的最佳方法
Best way to handle mixed synchronous and asynchronous errors in ExpressJS
使用 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()。
有什么改进建议吗?
考虑到使用了 promises,同步和异步错误都可以用 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 不支持承诺,async
函数体应该用 try..catch
包裹起来。考虑到 try..catch
对所有 async
中间件函数都是通用的,它可以移到一个 helper 中:
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 (...) => {...});
使用 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()。
有什么改进建议吗?
考虑到使用了 promises,同步和异步错误都可以用 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 不支持承诺,async
函数体应该用 try..catch
包裹起来。考虑到 try..catch
对所有 async
中间件函数都是通用的,它可以移到一个 helper 中:
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 (...) => {...});