Может ли исключение быть брошено вверх - PullRequest
4 голосов
/ 06 января 2011

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

Примером может быть. Если я проверяю загрузку при первом запуске, и она не удается, я могу предположить, что их память, возможно, была очищена. Но если я попытаюсь загрузить во время выполнения, я могу предположить, что память не была очищена (правильными средствами), и что-то должно быть.

    public void SaveToStorage(AccountCollection Collection)
    {
        try
        {
            var storage = IsolatedStorageSettings.ApplicationSettings;
            storage["defaultCollection"] = Collection;
            storage.Save();
        }
        catch (Exception ex)
        {
            // Do something meaningful here
        }
    }

    public AccountCollection LoadFromStorage()
    {
        try
        {
            AccountCollection collection;
            var storage = IsolatedStorageSettings.ApplicationSettings;
            storage.TryGetValue("defaultCollection", out collection);
            return collection;
        }
        catch (Exception ex)
        {
          // Do something meaningful here
        }

        return null;
    }

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

РЕДАКТИРОВАТЬ: Джон и Эндрю дали правильные ответы. Эндрю получит зеленую галочку, как я хотел бы сделать какую-то другую общую очистку в исходном классе.

Ответы [ 7 ]

11 голосов
/ 06 января 2011

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

catch (Exception ex)
{
    // Do something
    throw;
}

Редактировать

По какой-то причинеЯ прочитал это как C ++, поэтому удалил мои замечания о копировании исключения.

6 голосов
/ 06 января 2011

Если вы не поймаете исключение, оно будет распространяться вверх.

Вот как это работает. Не ставьте блоки try / catch везде. Размещайте их только там, где вы собираетесь обработать исключение.

4 голосов
/ 06 января 2011

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

catch(Exception ex)
{
    // Do your bit with ex

    throw;
}

Используя просто throw, вы сохраняете всю информацию об исключении, включая трассировку стека.

http://winterdom.com/2002/09/rethrowingexceptionsinc

2 голосов
/ 06 января 2011

Этот пример из MSDN звучит как то, что вы можете искать.

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

class TestTryCatch
{
    static int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException e)  // CS0168
        {
            System.Console.WriteLine(e.Message);
            //set IndexOutOfRangeException to the new exception's InnerException
            throw new System.ArgumentOutOfRangeException("index parameter is out of range.", e);
        }
    }
}

http://msdn.microsoft.com/en-us/library/ms173165(v=vs.80).aspx

1 голос
/ 06 января 2011

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

catch(Exception ex)
{
    // Do something...
    throw new MyOwnDataStorageException("message", ex);
}

Или вы можете просто ничего не делать, и исключение автоматически передается вызывающей стороне с полным стеком вызовов.

0 голосов
/ 06 января 2011

Если вы не можете сделать что-нибудь полезное, когда не можете поймать ожидание в AccountCollection (), тогда дайте ему всплыть до вызывающего метода и обработайте его там.

0 голосов
/ 06 января 2011

Вы можете просто выбросить исходное исключение (в вашем текущем коде, доступном как ex) в вашем блоке catch.Это действительно зависит от того, хотите ли вы обрабатывать какие-либо исключения в этих функциях.Если вы не хотите, поместите блоки try / catch снаружи (поместите их в вызывающую программу там, где вы хотите обработать исключение (я)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...