error-handler.js 4.06 KB
/**
 * 404 错误
 * @return {[type]}
 */
const headerModel = require('../models/header');
const logger = global.yoho.logger;
const helpers = global.yoho.helpers;
const sender = global.yoho.apmSender;
const hostname = require('os').hostname();
const routeEncode = require('./route-encode');
const _ = require('lodash');

const forceNoCache = (res) => {
    if (res && !res.finished) {
        res.set({
            'Cache-Control': 'no-cache',
            Pragma: 'no-cache',
            Expires: (new Date(1900, 0, 1, 0, 0, 0, 0)).toUTCString()
        });
    }
};


exports.notFound = () => {
    return (req, res) => {
        forceNoCache(res);

        res.status(404);

        if (req.xhr) {
            return res.json({
                code: 404,
                message: '抱歉,页面不存在!'
            });
        }
        return res.render('error/404', {
            module: 'common',
            page: 'error',
            title: '页面不存在 | Yoho!Buy有货 | 潮流购物逛不停',
            pageHeader: headerModel.setNav({
                navTitle: '抱歉,页面不存在!'
            }),
            pageFooter: true,
            isErr: true
        });
    };
};

/**
 * 服务器错误
 * @return {[type]}
 */
exports.serverError = () => {
    return (err, req, res, next) => {
        forceNoCache(res);
        const uid = req.user ? req.user.uid : 0;
        const udid = _.get(req, 'cookies.udid', 'yoho');

        if (req.isApmReport) {
            // 上报服务端错误
            sender.addMessage({
                measurement: 'error-report',
                tags: {
                    app: global.yoho.config.appName, // 应用名称
                    hostname,
                    type: 'server',
                    route: `[${req.method}]${_.get(req, 'route.path', '')}`, // 请求路由
                    reqID: req.reqID,
                    uid,
                    udid,
                    code: err.code || 500,
                    path: `[${req.method}]${routeEncode.getRouter(req)}`
                },
                fields: {
                    message: err.message,
                    stack: err.stack
                }
            });
        }

        if (err && err.code === 401) {
            logger.warn(`401 warn info:client_type=${req.query.client_type},req.user=${JSON.stringify(req.user)},req.query=${JSON.stringify(req.query)},cookies=${JSON.stringify(req.cookies)}`); // eslint-disable-line

            if (req.xhr) {
                return res.status(401).json(err);
            } else if (req.yoho.isApp) {
                if (err.lowVersion) {
                    return res.render('error/app-auth', {
                        module: 'common',
                        page: 'app-update',
                        localCss: true,
                        message: err.message
                    });
                }
                return res.render('error/app-auth', {
                    module: 'common',
                    page: 'app-redirect-login',
                    message: '请登录',
                    localCss: true,
                    refer: err.refer
                });
            } else {
                return res.redirect(helpers.urlFormat('/signin.html', {
                    refer: req.originalUrl
                }));
            }
        }

        logger.error(`error at path: ${req.url}`);
        logger.error(err);

        if (!res.headersSent) {
            res.status(err.code || 500);

            if (req.xhr) {
                return res.json({
                    code: 500,
                    message: '服务器错误!'
                });
            }

            return res.render('error/500', {
                err: err,
                module: 'common',
                page: 'error',
                title: '服务器错误 | Yoho!Buy有货 | 潮流购物逛不停',
                pageHeader: headerModel.setNav({
                    navTitle: '服务器错误!'
                }),
                pageFooter: true,
                isErr: true
            });
        }
        next(err);
    };
};