我们有一个非常大的复杂应用程序,它在启动时初始化了一个 ThreadException 处理程序,应用程序抛出的任何没有立即处理的异常都由这个 ThreadException 处理程序统一处理。
这主要是可行的......但是我们有几个自定义异常类型,我们想用这个异常处理程序来处理,并且由于某种原因,这些异常类型总是在 ThreadException 处理程序中显示为 System.ComponentModel.Win32Exception 类型,而不是我们的自定义类型。
我已经尝试了任何我能想到的故障排除方法,包括确保我们的自定义异常类实现所有推荐的构造函数,包括序列化构造函数。
附加信息...当我仅使用来自现有异常的消息创建一个新异常时,这会以 System.Exception 的形式出现。例如:
MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
throw new Exception(ex.Message);
工作正常,并在异常处理程序中作为 System.Exception 捕获。
但是,如果我尝试类似:
MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
throw new Exception(ex.Message, ex);
然后异常管理器捕获上面的 System.ComponentModel.Win32Exception 而不仅仅是一个 System.Exception。
为了完整起见,我想做的是:
throw new MSCSqlException(sqlQuery, sqlParams, sqlException);
并让 Application.ThreadException 处理程序接收正确类型的 MSCSqlException。
任何想法如何解决这个问题?我是否缺少与自定义错误类型相关的 Application.ThreadException 的一些怪癖?
我们的自定义异常类:
[Serializable]
public class MSCSqlException : Exception
{
public string SqlCommand { get; private set; }
public object[] SqlParameters { get; private set; }
public MSCSqlException()
{
}
public MSCSqlException(string message)
: base(message)
{
}
public MSCSqlException(string message, Exception inner) : base(message, inner)
{
}
public MSCSqlException(string command, object[] parameters, SqlException sx) : base(CreateUsefulMessage(sx, command, parameters), sx)
{
SqlCommand = command;
SqlParameters = parameters;
}
protected MSCSqlException(SerializationInfo info, StreamingContext context) : base(info, context)
{
SqlCommand = info.GetString("SqlCommand");
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("SqlCommand", SqlCommand);
base.GetObjectData(info, context);
}
public static string CreateUsefulMessage(SqlException sx, string sqlCommand, object[] sqlParameters)
{
string message = sx.Message + Environment.NewLine;
if(sqlParameters != null && sqlParameters.Count() > 0)
{
message = message + "Parameters:" + Environment.NewLine;
foreach(object sp in sqlParameters)
{
message = message + "\t" + sp.ToString() + Environment.NewLine;
}
}
message = message + "SQL Statement:" + Environment.NewLine;
message = message + sqlCommand;
return message;
}
}