entry-server.js 1.92 KB
import {createApp} from './app';
import {get} from 'lodash';

import {
  SET_ENV,
} from 'store/yoho/types';
const sender = global.yoho.apmSender;
const logger = global.yoho.logger;

const catchError = (err, context) => {
  logger.error(`[catchError], ${err}`);
  setImmediate(() => {
    try {
      sender.addMessage({
        measurement: 'error-report',
        tags: {
          app: 'yoho-app', // 应用名称
          hostname: context.hostname,
          type: 'server',
          route: context.route, // 请求路由
          uid: get(context, 'user.uid', 0),
          udid: context.udid,
          code: err.code || 500,
          path: context.path,
          url: encodeURIComponent(context.url),
          ip: context.env.clientIp
        },
        fields: {
          message: err.message,
          stack: err.stack,
          useragent: context.ua
        }
      });
    } catch (error) {
      logger.error(error);
    }
  });
};

export default context => {
  return new Promise((resolve, reject) => {
    const {app, router, store} = createApp(context);
    const {url, env} = context;

    store.commit(SET_ENV, env);
    router.push(url);
    router.onReady(() => {
      const matched = router.getMatchedComponents();

      if (matched.some(m => !m)) {
        catchError(new Error('导航组件为空'), context);
        router.push({name: 'error.500'});
        return resolve(app);
      }
      if (!matched.length) {
        return reject({code: 404, message: ''});
      }

      Promise.all(matched.map(({asyncData}) =>
        asyncData && asyncData({store, router: router.currentRoute})))
        .then(() => {
          context.state = store.state;
          return resolve(app);
        }).catch(e => {
          catchError(e, context);
          return resolve(app);
        });
    });

    router.onError(e => {
      catchError(e, context);
      router.push({name: 'error.500'});
      return resolve(app);
    });
  });
};