Обработка ошибки в блоке catch
От: .beginner  
Дата: 04.12.12 10:22
Оценка:
Мне довольно часто приходится писать похожие обработчики ошибок,
когда в try-catch в блоке catch нужно сделать что то, что может снова привести к ошибке.
я решаю эту проблему неизящно, пример:

    private void LoadSettings()
    {
      string fileName = @"c:\Settings.xml";
      bool needDelete = false;
      try
      {
        // Пробуем загрузить настройки из файла, но не уверен, что файл правильный
        gc1.MainView.RestoreLayoutFromXml(fileName);
      }
      catch (Exception ex)
      {
        // ставим флаг, что онужно грохнуть такой нехороший файл
        needDelete = true;
      }
      if (needDelete)
      {
        try
        {
          File.Delete(fileName);
        }
        catch (Exception ex)
        {
        }
      }
    }


Как то это громоздко. Нет ли способа делать это без двух блоков Try-catch и флага?
Спасибо за рекомендации!
Re: Обработка ошибки в блоке catch
От: Gremlin2 http://www.fb2library.net/
Дата: 04.12.12 12:02
Оценка:
Здравствуйте, .beginner, Вы писали:

B>Мне довольно часто приходится писать похожие обработчики ошибок,

B>когда в try-catch в блоке catch нужно сделать что то, что может снова привести к ошибке.
B>я решаю эту проблему неизящно, пример:
  Скрытый текст
B>
B>    private void LoadSettings()
B>    {
B>      string fileName = @"c:\Settings.xml";
B>      bool needDelete = false;
B>      try
B>      {
B>        // Пробуем загрузить настройки из файла, но не уверен, что файл правильный
B>        gc1.MainView.RestoreLayoutFromXml(fileName);
B>      }
B>      catch (Exception ex)
B>      {
B>        // ставим флаг, что онужно грохнуть такой нехороший файл
B>        needDelete = true;
B>      }
B>      if (needDelete)
B>      {
B>        try
B>        {
B>          File.Delete(fileName);
B>        }
B>        catch (Exception ex)
B>        {
B>        }
B>      }
B>    }

B>

B>Как то это громоздко. Нет ли способа делать это без двух блоков Try-catch и флага?
B>Спасибо за рекомендации!
А что мешает объединить всё в один блок?

    private void LoadSettings()
    {
      string fileName = @"c:\Settings.xml";
      bool needDelete = false;
      try
      {
        // Пробуем загрузить настройки из файла, но не уверен, что файл правильный
        gc1.MainView.RestoreLayoutFromXml(fileName);
      }
      catch (Exception ex)
      {
        try
        {
          File.Delete(fileName);
        }
        catch (Exception ex)
        {
        }
      }
    }
Re: Обработка ошибки в блоке catch
От: Kubyshev Andrey  
Дата: 05.12.12 02:15
Оценка: +1
Мне кажется здесь тебе нужен try {} finally {}
Re[2]: Обработка ошибки в блоке catch
От: Аноним  
Дата: 05.12.12 04:00
Оценка:
Здравствуйте, Kubyshev Andrey, Вы писали:

KA>Мне кажется здесь тебе нужен try {} finally {}


+1 к try-finally, т.к. обработка исключения File.Delete(fileName); просто глотает их.

Другое дело, что если мы хотим залогировать это исключение, то try-finally придется разворачивать обратно.
Re: Обработка ошибки в блоке catch
От: elmal  
Дата: 05.12.12 04:33
Оценка:
Здравствуйте, .beginner, Вы писали:

B>Как то это громоздко. Нет ли способа делать это без двух блоков Try-catch и флага?

B>Спасибо за рекомендации!
Делается так:
Во первых, операции с файлами выносятся в отдельную свою обертку.
Например MyFileUtils.safeDeleteFile(fileName), который не будет кидать такие исключения. В результате это будет написано один раз;
Соответственно это все переписывается в:
    private void LoadSettings(string fileName)
    {
      try
      {
        // Пробуем загрузить настройки из файла, но не уверен, что файл правильный
        gc1.MainView.RestoreLayoutFromXml(fileName);
      }
      catch (Exception ex)
      {
        MyFileUtils.safeDeleteFile(fileName)
      }
    }

Если используется какой нидь Dependency Injection Framework, то это будет не утилитный класс, а сервис. Который можно будет подменить на моки в процессе юнит тестирования.
Теперь из ужасов здесь остается только строка вида gc1.MainView.RestoreLayoutFromXml(fileName), что ахтунг еще тот, но как от этого ужаса избавляться это отдельный разговор.
Re: Обработка ошибки в блоке catch
От: Аноним  
Дата: 05.12.12 05:42
Оценка:
Здравствуйте, .beginner, Вы писали:

B>Мне довольно часто приходится писать похожие обработчики ошибок,

B>когда в try-catch в блоке catch нужно сделать что то, что может снова привести к ошибке.
B>я решаю эту проблему неизящно, пример:

B>
B>    private void LoadSettings()
B>    {
B>      string fileName = @"c:\Settings.xml";
B>      bool needDelete = false;
B>      try
B>      {
B>        // Пробуем загрузить настройки из файла, но не уверен, что файл правильный
B>        gc1.MainView.RestoreLayoutFromXml(fileName);
B>      }
B>      catch (Exception ex)
B>      {
B>        // ставим флаг, что онужно грохнуть такой нехороший файл
B>        needDelete = true;
B>      }
B>      if (needDelete)
B>      {
B>        try
B>        {
B>          File.Delete(fileName);
B>        }
B>        catch (Exception ex)
B>        {
B>        }
B>      }
B>    }

B>


B>Как то это громоздко. Нет ли способа делать это без двух блоков Try-catch и флага?

B>Спасибо за рекомендации!

Да вообще странный код. Программа сталкивается с двумя ошибками сразу и продолжает работать никому об этом не сообщая.
Re: Обработка ошибки в блоке catch
От: dimaka Россия http://dmitry-pavlov.com
Дата: 05.12.12 08:46
Оценка: 2 (1)
Можно так:


        private void LoadSettings()
        {
            const string fileName = @"c:\Settings.xml";

            // Пробуем загрузить настройки из файла, и удаляем его если не получилось
            TryExecute(() => gc1.MainView.RestoreLayoutFromXml(fileName), () => System.IO.File.Delete(fileName));
        }

        private void TryExecute(Action operation, Action errorHandler)
        {
            try
            {
                operation.Invoke();
            }
            catch (Exception ex)
            {
                // Log ex here
                if (errorHandler != null) TryExecute(errorHandler, null);
            }
        }


TryExecute можно использовать и для других вызовов.
Remote ASP.NET / C# Developer
Re[2]: Обработка ошибки в блоке catch
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 06.12.12 21:27
Оценка:
Здравствуйте, elmal, Вы писали:

E>Если используется какой нидь Dependency Injection Framework, то это будет не утилитный класс, а сервис


Вот нафига?
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: Обработка ошибки в блоке catch
От: elmal  
Дата: 07.12.12 05:41
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Вот нафига?

Довольно недавно обсуждали это
здесь
Автор: elmal
Дата: 03.12.12
Re[4]: Обработка ошибки в блоке catch
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 07.12.12 09:34
Оценка:
Здравствуйте, elmal, Вы писали:

AVK>>Вот нафига?

E>Довольно недавно обсуждали это

Ага, а потом из-за таких применений начинаются рассказы, что IoC это зло.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.