我坚持如何在Express.js应用程序中设计错误处理。 在Express中处理错误的最佳设计实践是什么?
据我了解,我可以通过两种不同的方式处理错误:
第一种方法是使用错误中间件,并且当路由中抛出错误时,将错误传播到该错误中间件。这意味着我们必须在中间件本身中插入错误处理程序的逻辑(注意,这里的中间件故意保持简单)。
app.post('/someapi', (req, res, next) => {
if(req.params.id == undefined) {
let err = new Error('ID is not defined');
return next(err);
}
// do something otherwise
});
app.use((err, req, res, next)=>{
// some error logic
res.status(err.status || 500).send(err);
});
另一种选择是在错误发生时立即处理错误。这意味着逻辑必须位于路径本身
app.post('/someapi', (req, res, next) => {
if(req.params.id == undefined) {
let err = new Error('ID is not defined');
// possibly add some logic
return res.status(ErrorCode).send(err.message);
}
// do something otherwise
});
最好的方法是什么,最好的设计方法是什么?
谢谢
答案 0 :(得分:0)
我认为有更多的案例,但主要的想法是使用中间件设计。将验证逻辑添加到此中间件。
yourRouter.post('/message', routerValidator.messageValidator, yourController.saveMessage.bind(yourController));
以下是我的示例结构;
// controller
const BaseRoute = require('../infra/base/BaseRoute');
const log = require('./../../utils/log-helper').getLogger('route-web');
const { ErrorTypes } = require('../infra/middlewares/ErrorMiddleware');
const GameService = require('../../service/GameService');
const { SystemMessages } = require('../../statics/default_types');
module.exports = class WebController {
constructor() {
this._logger = log;
this._gameService = new GameService();
}
getGameInfo(req, res) {
var self = this;
try {
const info = self._gameService.getGameInfo(req.body.query);
return BaseRoute.success(res, { info });
} catch (err) {
self._logger.error('Something went wrong while getting game information', err);
return BaseRoute.internalError(res, SystemMessages.GENERIC_ERROR, req.getErrorCode(ErrorTypes.UNHANDLED, 1));
}
}
};
//路由器索引
const express = require('express');
const ErrorMiddleware = require('../infra/middlewares/ErrorMiddleware').ErrorMiddlewarePath;
const baseValidator = require('../infra/validators/BaseRouterValidator');
const AndroidController = require('./AndroidController');
const IosController = require('./IosController');
const WebController = require('./WebController');
const AndroidRouter = express.Router();
const IosRouter = express.Router();
const WebRouter = express.Router();
const androidController = new AndroidController();
const iosController = new IosController();
const webController = new WebController();
AndroidRouter.post('/message', ErrorMiddleware(1), baseValidator.teamQueryValidator, androidController.getGameInfo.bind(androidController));
IosRouter.post('/message', ErrorMiddleware(1), baseValidator.teamQueryValidator, iosController.getGameInfo.bind(iosController));
WebRouter.post('/message', ErrorMiddleware(1), baseValidator.teamQueryValidator, webController.getGameInfo.bind(webController));
module.exports = {
AndroidRouter,
IosRouter,
WebRouter
};
//验证器
const log = require('../../../utils/log-helper').getLogger('route-validator-base');
const BaseRoute = require('../base/BaseRoute');
const _ErrorTypes = require('../middlewares/ErrorMiddleware').ErrorTypes;
function teamQueryValidator(req, res, next) {
if (!req.body || !req.body.query) {
const params = req.body ? JSON.stringify(req.body) : 'Empty';
log.error('Invalid Parameters req body', params);
return BaseRoute.httpError(res, 'Bir takım adı giriniz..', 400, req.getErrorCode(_ErrorTypes.VALIDATION, 1));
}
return next();
}
module.exports = {
teamQueryValidator
};
// app.js指定表达
this._router = require('./src/route/api/index');
this._ErrorMiddleware = require('./src/route/infra/middlewares/ErrorMiddleware').ErrorMiddlewareRouter;
this.app.use('/api/android', this._ErrorMiddleware(1), this._router.AndroidRouter);
this.app.use('/api/ios', this._ErrorMiddleware(2), this._router.AndroidRouter);
this.app.use('/api/web', this._ErrorMiddleware(3), this._router.WebRouter);
答案 1 :(得分:0)
在Express中处理错误的最佳设计方法是什么?
没有最好的设计,这都是主观的。
据我了解,我可以通过两种不同的方式处理错误:
正确。您使用了第一个错误中间件,然后直接在路由处理程序中处理错误。
对我而言,将错误处理逻辑与业务逻辑分开是有意义的。它使代码更清晰。所以前者(错误中间件)会更好IMO。
对于不同的错误,您将拥有不同的错误处理程序。