C # Поймать перебрасывание / распространение для определенного типа исключения - PullRequest
1 голос
/ 13 января 2012

Я пытаюсь распространить на мой пользовательский интерфейс исключение GatewayConnectionFailedException, как вы можете видеть.Я хочу, чтобы этот код перехватывал все, кроме того исключения, которое я хочу, чтобы уровень представления перехватывал, чтобы уведомить пользователя о том, что проблема была в базе данных, чтобы он мог пойти и исправить ее.Моя проблема заключается в том, что когда я выкидываю его в первый раз, я получаю исключение GatewayConnectionFailedException, которое не обрабатывается кодом пользователя в предложении перехвата GatewayException.

Также важно отметить, что исключение GatewayConnectionFailedException расширяет GatewayException, расширяющее Exception.Что-то мне не хватает или мне придется перенести весь улов на уровень презентации?

        try
        {
             something();
        }
        catch (GatewayConnectionFailedException gcfe)
        {
            throw;
        }
        catch (GatewayException ge)
        {
            if (ge.GetType() == typeof(GatewayConnectionFailedException))
                throw;
            string errMsg = "Records could not be retrieved due to a data gateway error. " + GetTypeInfo();
            _logger.Error(errMsg + "\r\n{0}", ge);
        }
        catch (Exception e)
        {
            if (e.GetType() == typeof(GatewayConnectionFailedException))
                throw;
            string errMsg = "Records could not be retrieved due to an unexpected error. " + GetTypeInfo();
            _logger.Error(errMsg + "\r\n{0}", e);
        }

Ответы [ 6 ]

2 голосов
/ 13 января 2012

Глупый вопрос ... твой код пользовательского интерфейса пробовал при вызове этого слоя?Что-то должно справиться с этим вторым броском ...

В двух словах, звучит так, будто вы пытаетесь сделать это:

using System;

namespace ConsoleApplication1
{
    class ExceptionA : Exception
    {
        public override string Message
        {
            get
            {
                return "Exception A";
            }
        }
    }

    class ExceptionB : ExceptionA
    {
        public override string Message
        {
            get
            {
                return "Exception B";
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                DoThing();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught in 'UI' code: " + ex.Message);
            }
        }

        static void DoThing()
        {
            try
            {
                throw new ExceptionB();
            }
            catch (ExceptionB ex)
            {
                Console.WriteLine("Caught B");
                throw;
            }
            catch (ExceptionA ex)
            {
                Console.WriteLine("Caught A");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught Generic");
            }
        }
    }
}

Что дает такой вывод:

Пойманный B
Пойманный в коде 'UI': Исключение B
Нажмите любую клавишу для продолжения ...

Похоже, у вас нет ничего, что перехватывает 2-е выброшенное исключениепочему это "необработанный".Если мы закомментируем try-catch в main, мы получим необработанное исключение:

static void Main(string[] args)
        {
            //try
            //{
            DoThing();
            //}
            //catch (Exception ex)
            //{
            //Console.WriteLine("Caught in 'UI' code: " + ex.Message);
            //}
        }

Получив следующий вывод:

Caught B

Unhandled Exception:ConsoleApplication1.ExceptionB: Исключение B в ConsoleApplication1.Program.DoThing () в C: \ Users \ Giovanni \ AppData \ Local \ T временных проектах \ ConsoleApplication1 \ Program.cs: строка 50 в ConsoleApplication1.Program.Main (String [] args)в C: \ Users \ Giovanni \ AppDa ta \ Local \ Temporary Projects \ ConsoleApplication1 \ Program.cs: строка 33 Нажмите любую клавишу для продолжения.,.

1 голос
/ 13 января 2012

, чтобы начать ваш try catch, излишне. первый улов обработает GatewayConnectionFailedException, остальные уловы никогда не будут иметь тип GatewayConnectionFailedException, поскольку они были обработаны первым уловом. поэтому код можно упростить до

try
{
    something();
}
catch (GatewayConnectionFailedException)
{
    throw;
}
catch (GatewayException e)
{
    _logger.Error(e.Message, e);
}

Теперь, как пользовательский интерфейс будет обрабатывать это, зависит от того, как вы обрабатываете исключение. если вы просто сгенерируете исключение, то вам также понадобится попытка перехвата на уровне представления. Однако, если тип возвращаемого значения этого слоя возвратил объект как

class Result<T>
{
     T Value {get;set;}
     Exception Error {get;set;}
}

Тогда вы можете просто обработать тип без необходимости try / catch на уровне представления.

Также стоит отметить, что вы ловите и почему вы пытаетесь поймать это. как правило, вы не хотите перехватывать Exception, кроме как на прикладном уровне, где вы регистрируете ошибку и терпите неудачу. Исключения должны быть исключительными, и поэтому возможны только те исключения, которые вы ожидаете, и причины их возникновения. в противном случае пусть они всплывают.

1 голос
/ 13 января 2012

Перехват GatewayConnectionFailedException должен решить вашу проблему, а в блоке catch просто выполните throw, , не бросайте объект исключения . Ответ Энди правильный.

Во-вторых, я предполагаю, что GatewayConnectionFailedException наследуется от GatewayException.

Выберите catch последовательность в порядке возрастания наследования, сначала должен стоять дочерний класс, а затем базовый класс.

catch(Child){}
catch(Base){}
catch(Exception) {} //Base class for all exceptions
1 голос
/ 13 января 2012

Трудно сказать, чего не хватает без полной картины, но одна важная вещь, которую вы должны бросать исключения по-другому.Синтаксис должен быть

throw;

у вас будет полная трассировка стека. Подробнее .

1 голос
/ 13 января 2012

От одного пункта до отказа, хотя это может не исправить исключение, если вы перехватываете и перебрасываете исключение, используйте вместо этого код:

catch (GatewayConnectionFailedException)
{
    throw;
}

таким образом, трассировка стека более точно отражает ход программы.Это может не решить проблему, хотя.

1 голос
/ 13 января 2012

Вместо использования throw exceptionName попробуйте только throw. Редактировать 1: Попробуйте перехватить все исключения в одном блоке, а затем выбросить исключение, только если это GatewayConnectionFailedException

try
{
     something();
}
catch (Exception e)
{
    if (e.GetType() == typeof(GatewayConnectionFailedException))
        throw;
    string errMsg = "Records could not be retrieved due to an unexpected error. " + GetTypeInfo();
    _logger.Error(errMsg + "\r\n{0}", e);
}
...