ABP 异常处理 第四篇

Posted topguntopgun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABP 异常处理 第四篇相关的知识,希望对你有一定的参考价值。

异常ABP异常分类

技术分享图片

 

ABP的异常基类源代码 ABPException的源代码如下

   /// <summary>
    /// Base exception type for those are thrown by Abp system for Abp specific exceptions.
    /// </summary>
    [Serializable]
    public class AbpException : Exception
    {
        /// <summary>
        /// Creates a new <see cref="AbpException"/> object.
        /// </summary>
        public AbpException()
        {

        }

        /// <summary>
        /// Creates a new <see cref="AbpException"/> object.
        /// </summary>
        public AbpException(SerializationInfo serializationInfo, StreamingContext context)
            : base(serializationInfo, context)
        {

        }

        /// <summary>
        /// Creates a new <see cref="AbpException"/> object.
        /// </summary>
        /// <param name="message">Exception message</param>
        public AbpException(string message)
            : base(message)
        {

        }

        /// <summary>
        /// Creates a new <see cref="AbpException"/> object.
        /// </summary>
        /// <param name="message">Exception message</param>
        /// <param name="innerException">Inner exception</param>
        public AbpException(string message, Exception innerException)
            : base(message, innerException)
        {

        }
    }

 

ABP通过ABPExceptionFilter拦截异常的源代码

    public class AbpExceptionFilter : IExceptionFilter, ITransientDependency
    {
        //日志记录
        public ILogger Logger { get; set; }

        //事件总线
        public IEventBus EventBus { get; set; }

        // 错误信息构建器
        private readonly IErrorInfoBuilder _errorInfoBuilder;

        // AspNetCore 相关的配置信息
        private readonly IAbpAspNetCoreConfiguration _configuration;

        public AbpExceptionFilter(IErrorInfoBuilder errorInfoBuilder, IAbpAspNetCoreConfiguration configuration)
        {
            _errorInfoBuilder = errorInfoBuilder;
            _configuration = configuration;

            Logger = NullLogger.Instance;
            EventBus = NullEventBus.Instance;
        }

        public void OnException(ExceptionContext context)
        {
            if (!context.ActionDescriptor.IsControllerAction())
            {
                return;
            }

            // // 获得方法的包装特性。决定后续操作,如果没有指定包装特性,则使用默认特性
            var wrapResultAttribute =
                ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(
                    context.ActionDescriptor.GetMethodInfo(),
                    _configuration.DefaultWrapResultAttribute
                );

            //需要记录日志
            if (wrapResultAttribute.LogError)
            {
                LogHelper.LogException(Logger, context.Exception);
            }

            //重构异常错误处理
            if (wrapResultAttribute.WrapOnError)
            {
                HandleAndWrapException(context);
            }
        }

        /// <summary>
        /// 包装异常
        /// </summary>
        /// <param name="context"></param>
        protected virtual void HandleAndWrapException(ExceptionContext context)
        {
            //判断返回类型是否是objectresult,不是直接返回
            if (!ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
            {
                return;
            }

            // 设置 HTTP 上下文响应所返回的错误代码,由具体异常决定。
            context.HttpContext.Response.StatusCode = GetStatusCode(context);

            context.Result = new ObjectResult(
                new AjaxResponse(
                    _errorInfoBuilder.BuildForException(context.Exception),
                    context.Exception is AbpAuthorizationException
                )
            );

            //// 触发异常处理事件
            EventBus.Trigger(this, new AbpHandledExceptionData(context.Exception));


            // 处理完成,将异常上下文的内容置为空
            context.Exception = null; //Handled!
        }


        //根据不同的异常返回不同的status
        protected virtual int GetStatusCode(ExceptionContext context)
        {
            if (context.Exception is AbpAuthorizationException)
            {
                return context.HttpContext.User.Identity.IsAuthenticated
                    ? (int)HttpStatusCode.Forbidden //403
                    : (int)HttpStatusCode.Unauthorized; //401
            }

            if (context.Exception is AbpValidationException)
            {
                return (int)HttpStatusCode.BadRequest;  //400
            }

            if (context.Exception is EntityNotFoundException)
            {
                return (int)HttpStatusCode.NotFound; //404
            }

            return (int)HttpStatusCode.InternalServerError;  //500
        }
    }

 

ABP异常处理包装返回的结果结构,如果不想包装,请使用特性 DontWarpResult

{
  "result": {
    "totalCount": 0,
    "items": []
  },
  "targetUrl": null,
  "success": true,
  "error": null,
  "unAuthorizedRequest": false,
  "__abp": true
}

 

ABP正常接口返回的数据结构如下

public abstract class AjaxResponseBase
{
    // 目标 Url 地址
    public string TargetUrl { get; set; }

    // 接口调用是否成功
    public bool Success { get; set; }

    // 当接口调用失败时,错误信息存放在此处
    public ErrorInfo Error { get; set; }

    // 是否是未授权的请求
    public bool UnAuthorizedRequest { get; set; }

    // 用于标识接口是否基于 Abp 框架开发
    public bool __abp { get; } = true;
}

 

显示额外的异常处理,需要在模块预处理的代码中加入:

Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;

 

实时监听异常处理,如果需要发生报警,重写异常处理事件

public class ExceptionEventHandler : IEventHandler, ITransientDependency
{
    /// 

    /// Handler handles the event by implementing this method.
    /// 

    /// Event data
    public void HandleEvent(AbpHandledExceptionData eventData)
    {
        Console.WriteLine($"当前异常信息为:{eventData.Exception.Message}");
    }
}

 

以上是关于ABP 异常处理 第四篇的主要内容,如果未能解决你的问题,请参考以下文章

第四篇:数据预处理 - 缺失值处理

第四篇 函数

混合编程jni 第四篇之引用和异常

混合编程jni 第四篇之引用和异常

ABP异常处理

ABP源码分析四十七:ABP中的异常处理