异常可以在其他类、程序集或抽象类中处理吗?

本文关键字:抽象类 处理 程序集 其他 异常 | 更新日期: 2023-09-27 18:10:58

我认为需要多次复制和粘贴以下错误处理代码。在Catch语句中工作时,我有哪些选择?

  • 在这样做的过程中,我会丢失有价值的信息吗?(例如:异常被重新包装在另一个异常中,或者丢失堆栈信息)

  • 如何区分myAbstractClass中的"throw"和下面的Select方法中的"throw"?

下面是我想复制的示例代码

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, vs网络vs文件,但不是身份验证)

        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...
        }

但是对于上面的代码,我不清楚最终用户如何选择或覆盖我的事件处理方法

异常可以在其他类、程序集或抽象类中处理吗?

您可以这样做。重要的是,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;
    }
}

您只能在catch子句中直接调用throw;,而throw e;可以在您有异常实例e的任何地方调用。它们之间的区别在于,throw;在保持其原始堆栈跟踪完整的情况下重新抛出异常,而throw e;重置堆栈跟踪,以便看起来异常最初是由throw e;抛出的——这在调试时可能非常烦人。因此,我建议您将switch语句提取到一个单独的方法中,该方法将StorageClientException作为参数,但将throw;直接保留在catch子句中。