Сохранение типа переброшенного исключения - PullRequest
4 голосов
/ 02 марта 2010

Я пишу класс, который выполняет операции с несколькими потоками. Вот пример того, что я делаю сейчас

Dictionary<int, int> dict = new Dictionary<int, int>(_Streams.Count);
for (int i = 0; i < _Streams.Count; i++)
{
    try
    {
        dict.Add(i, _Streams[i].Read(buffer, offset, count));
    }
    catch (System.IO.IOException e)
    {
        throw new System.IO.IOException(String.Format("I/O exception occurred in stream {0}", i), e);
    }
    catch (System.NotSupportedException e)
    {
        throw new System.NotSupportedException(String.Format("The reading of the stream {0} is not supported", i), e);
    }
    catch (System.ObjectDisposedException e)
    {
        throw new System.ObjectDisposedException(String.Format("Stream {0} is Disposed", i), e);
    }
}
int? last = null;
foreach (var i in dict)
{
    if (last == null)
        last = i.Value;
    if (last != i.Value)
        throw new ReadStreamsDiffrentExecption(dict);
    last = i.Value;
}
return (int)last;

Я бы хотел упростить мой код до

Dictionary<int, int> dict = new Dictionary<int, int>(_Streams.Count);
for (int i = 0; i < _Streams.Count; i++)
{
    try
    {
        dict.Add(i, _Streams[i].Read(buffer, offset, count));
    }
    catch (Exception e)
    {
        throw new Exception(String.Format("Exception occurred in stream {0}", i), e);
    }
}
int? last = null;
foreach (var i in dict)
{
    if (last == null)
        last = i.Value;
    if (last != i.Value)
        throw new ReadStreamsDiffrentExecption(dict);
    last = i.Value;
}
return (int)last;

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

Ответы [ 5 ]

3 голосов
/ 02 марта 2010

Я бы посоветовал не перехватывать эти исключения вообще ...

Добавляемую вами информацию можно (в основном) почерпнуть из стека-вывода.перехватывать и переносить в специфичное для библиотеки исключение:

 catch (Exception e)
 {
    throw new ReadStreamsErrorExecption(
      String.Format("Exception occurred in stream {0}", i), e);
 }
1 голос
/ 02 марта 2010

Одна малоизвестная хитрость .NET заключается в том, что вы МОЖЕТЕ добавить информацию в Исключение, не оборачивая ее. Каждое исключение имеет словарь .Data, который вы можете заполнить дополнительной информацией, например,

try
{
   ...
}
catch (FileNotFoundException ex)
{
   ex.Data.Add("filename", filename);
   throw;
}

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

В приложении ASP.NET вы, возможно, захотите добавить URL, имя пользователя, источник ссылки, содержимое файлов cookie ... в словарь .Data, прежде чем обработчик ошибок вашего приложения примет его.

1 голос
/ 02 марта 2010

Обычно правило, которое я взял из блогов Эрика Липпертса, заключается в том, что вы должны фиксировать исключение, только если вы собираетесь что-то с этим сделать.

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

throw;

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

1 голос
/ 02 марта 2010

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

1 голос
/ 02 марта 2010

Я думаю, у вас есть небольшая проблема в работе с вашим исключением.

  1. Вы не должны бросать базовый класс Exception, а что-то более конкретное, чтобы они могли справиться с этим.
  2. Является ли значение id чем-то действительно ценным из диагностической функции?

Я бы посмотрел, что вы делаете, и посмотрел бы, нужно ли вам обернуть исключение.

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