Application.ThreadException получает неправильный тип Win32Exception
У нас есть очень большое сложное приложение, в котором обработчик 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;
}
}
1 ответ
Мы наконец выяснили это... проблема заключается в ошибке или возможности того, как.Net обрабатывает исключения, возникающие в фоновом рабочем событии Completed. По какой-то причине кажется, что в этом случае.Net время выполнения передает самое внутреннее исключение из трассировки стека в обработчик ThreadException вместо ожидаемого внешнего исключения. Это самое внутреннее исключение, когда генерируется SQLException, является Win32Exception.
Больше информации об этом здесь:
Application.ThreadException получает неправильный тип Win32Exception