Express.js设计错误处理

时间:2018-06-19 08:17:32

标签: node.js express design-patterns

我坚持如何在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
});

最好的方法是什么,最好的设计方法是什么?

谢谢

2 个答案:

答案 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。

对于不同的错误,您将拥有不同的错误处理程序。