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

Другие вопросы по тегам