Может ли исключение быть обработано в другом классе, сборке или абстрактном классе? - PullRequest
1 голос
/ 11 октября 2011

Я вижу необходимость скопировать и вставить следующий код обработки ошибок несколько раз.Какие у меня варианты при работе с оператором Catch?

  • При этом я потеряю ценную информацию в процессе?(пример: переупакованы ли исключения в другое исключение или потеря информации о стеке)

  • Как кто-то может определить разницу между «throw» в myAbstractClass и одним в методе Select ниже?

Вот пример кода, который я хочу скопировать

public class StackUserDataSource : AbstractEnhancedTableDataSource<StackUserDataServiceContext>
{
  //.. stuff

 public IEnumerable<StackUserDataModel> Select() 
    {
        try
        {
            var results = from c in _ServiceContext.StackUserTable
                          select c;

            var query = results.AsTableServiceQuery();
            var queryResults = query.Execute();

            return queryResults;
        }
        catch (StorageClientException e)
        {

           // Todo: consider sticking this in another central location    
            switch (e.ErrorCode)
            {
                case StorageErrorCode.AccessDenied:
                    break;
                case StorageErrorCode.AccountNotFound:
                    break;
                case StorageErrorCode.AuthenticationFailure:
                    break;
                // ... Yadda yadda, handle some exceptions, not others.. this is a demo.
                case StorageErrorCode.TransportError:
                    break;
                default:
                    break;
            }
            throw;
        }
    }

Обновление :

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

        try
        {
            var results = from c in _ServiceContext.StackUserTable
                          select c;

            var query = results.AsTableServiceQuery();
            var queryResults = query.Execute();

            return queryResults;
        }
        catch (MyExternalExceptionHelperDLL e)
        {
            // all exceptions referenced in MyExternalHelper are passed below
            MyExternalExceptionHelper.ProcessException(e);
         }
         catch (exception)
        {
         }

Поскольку MyExternalExceptionHelperDLL, вероятно, не может динамически выбирать и выбирать, что прослушивать (т. Е. SQL, сеть или файл, но не аутентификация)

        try
        {
            var results = from c in _ServiceContext.StackUserTable
                          select c;

            var query = results.AsTableServiceQuery();
            var queryResults = query.Execute();

            return queryResults;
        }
         catch (exception e)
        {
           MyExternalExceptionHelper.ProcessException(e);

           // The problem is that I don't know how to catch exceptions thrown from that static method above,
           // or how to override that exception handling...
        }

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

Ответы [ 2 ]

1 голос
/ 11 октября 2011

Вы могли бы сделать что-то вроде этого. Важной частью является то, что throw должен находиться в исходном блоке catch, чтобы сохранить трассировку стека.

public IEnumerable<StackUserDataModel> Select() 
{
    try
    {
        ...
    }
    catch (StorageClientException e)
    {
       // You could do this if there is no fancy processing to do
       if (!IsCatchableException(e))
          throw;
    }
}

bool IsCatchableException(StorageClientException e)
{
    ... optionally do some fancy processing of the exception, e.g. logging....
    switch (e.ErrorCode)
    {
        case StorageErrorCode.AccessDenied:
        case StorageErrorCode.AccountNotFound:
        ....
        return true;
    }
}
1 голос
/ 11 октября 2011

Вы можете вызвать throw; только внутри предложения catch, тогда как throw e; можно вызвать в любой точке, где у вас есть экземпляр исключения e.Разница между ними заключается в том, что throw; перебрасывает исключение, сохраняя при этом исходную трассировку стека, в то время как throw e; сбрасывает трассировку стека, так что создается впечатление, что исключение было первоначально выдано throw e; - что может быть довольно раздражающим при отладке.,Поэтому я предлагаю вам извлечь оператор switch в отдельный метод, который принимает StorageClientException в качестве параметра, но сохраняет throw; непосредственно в предложении catch.

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