'use strict';

/**
 * Controller 和 Service 抛出异常处理
 * @author bin fong
 * @return {function} function
 */
module.exports = () => {
  return async function errorHandler(ctx, next) {
    let transaction;
    try {

      //可以从这边文章了解到原理
      //http://www.cnblogs.com/cloud-/p/7239819.html
      //有点类似，中间件执行的时候会一个一个被装载，然后当执行到next 之后，会执行下一个中间件，等该中间件执行完成之后，又会返回执行next下面的代码
      await next();
    } catch (err) {
      // 所有的异常都在 app 上触发一个 error 事件，框架会记录一条错误日志
      ctx.app.emit('error', err, ctx);

      const status = err.status || 500;

      // 生产环境时 500 错误的详细错误内容不返回给客户端，因为可能包含敏感信息
      const error = status === 500 && ctx.app.config.env === 'prod'
        ? '系统内部错误'
        : err.message;

      // 从 error 对象上读出各个属性，设置到响应中
      ctx.body = { error };

      if (status === 422) {
        ctx.body.detail = err.errors;
      }
      ctx.status = status;
    }
  };
};
