Exception捕捉问题

昨天线上日志有错误提示。内容大概是返回到页面提示的异常信息后,日志又标记了和业务不相关的Exception。初步诊断程序没有出现异常,异常信息外包了一层try..catch,catch捕捉到的exception的一些代码错误位置等信息。这让我们当时很迷茫。

          try
            {
                if (sfbz)
                {
                    throw new FailedException("操作异常,已收费处方不允许变更");
                }
            }
            catch (Exception e)
            {
                LogCore.Error("SaveMedicalRecord error", e);
                throw;
            }

经过研究发现,主要是框架底层两个方面的问题

1.FailedException派生自基类Exception,根据业务需求重新定义了对象,却没有继承基类的message虚拟字段。导致Exception无法捕捉派生类的Message详情,抛出基类的异常信息。

//...FailedException
using System;

/// <summary>
/// 业务处理失败的可预测异常
/// </summary>
public class FailedException : Exception
{
	/// <summary>
	/// 错误代码
	/// </summary>
	public string Code
	{
		get;
		set;
	}

	/// <summary>
	/// 错误描述
	/// </summary>
	public string Msg
	{
		get;
		set;
	}

	/// <summary>
	/// 是否记入日志,默认false,不记入日志
	/// </summary>
	public bool Log
	{
		get;
		set;
	}

	/// <summary>
	/// 构造函数
	/// </summary>
	public FailedException()
	{
	}

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="msg">错误描述</param>
	public FailedException(string msg)
	{
		Msg = msg;
	}

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="code">错误代码</param>
	/// <param name="msg">错误描述</param>
	public FailedException(string code, string msg)
	{
		Code = code;
		Msg = msg;
	}

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="code">错误代码</param>
	/// <param name="msg">错误描述</param>
	/// <param name="log">是否记入日志</param>
	public FailedException(string code, string msg, bool log)
	{
		Code = code;
		Msg = msg;
		Log = log;
	}
}

2.日志问题。系统如何判断异常是系统用户的提示还是代码bug呢?先展示代码

/// <summary>
/// 过滤器 全局异常捕获,防止返回500
/// </summary>
public class HandlerErrorAttribute : HandleErrorAttribute
{
	/// <summary>
	/// (重写)Called when an exception occurs.
	/// </summary>
	/// <param name="context"></param>
	public override void OnException(ExceptionContext context)
	{
		FailedException ex2;
		if (!(context.Exception is FailedException))
		{
			ILogger logger = AppLogger.Instance;
			if (logger != null)
			{
				Exception ex = context.Exception;
				while (ex.InnerException != null)
				{
					ex = ex.InnerException;
				}
				logger.Error(ex.Message, ex);
			}
		}
		else 
		if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
		{
			context.ExceptionHandled = true;
			context.HttpContext.Response.StatusCode = 200;
			Exception innerEx = context.Exception;
			if (!(innerEx is FailedException))
			{
				while (innerEx.InnerException != null)
				{
					innerEx = innerEx.InnerException;
				}
			}
			context.Result = new ContentResult
			{
				Content = new AjaxResult
				{
					state = ResultType.error.ToString(),
					code = ((context.Exception is FailedException) ? (((FailedException)context.Exception).Code ?? "").ToUpper() : "SYSTEM_ERROR"),
					message = ((context.Exception is FailedException) ? ((FailedException)context.Exception).Msg : innerEx.Message),
					exStackTrace = ((context.Exception is FailedException) ? null : innerEx.StackTrace),
					InnerException = ((innerEx is FailedException) ? null : innerEx.InnerException)
				}.ToJson()
			};
		}
		else
		{
			base.OnException(context);
		}
	}
}

代码显示,只要捕捉到异常,就进HandlerErrorAttribute.OnException().主要是两个判断。第一个if非Failedception时为true。意思是Exception进入到该断代码。以下是记录日志详情的地方

logger.Error(ex.Message, ex);

很明显抛出"SaveMedicalRecord error" 异常日志是这段代码记录的。

第二个判断是ajax请求。主要是把当前返回结果设置为成功,整合当前错误信息为json串,用result接收后返回到页面给用户提示。诠释了下面代码,为什么初步诊断它没有记录下来

 throw new FailedException("操作异常,已收费处方不允许变更");

 

以上是昨天遇到的问题整理,刚开始自己写博客,表达和逻辑方面有些欠缺,小白请多指教。谢谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值