2011-10-10 54 views
1

我看到需要复制并粘贴以下错误处理代码几次。在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... 
     } 

但使用上面的代码,我不清楚最终用户如何选择或重写我的事件处理方法。

+0

可以拨打一个'catch'块就像其他地方的辅助方法...... – mellamokb

+0

是否有一个原因,长期'之开关语句什么也不做? –

+0

谢谢@mellamokb,我刚刚更新了这个问题...... – LamonteCristo

回答

1

你可以做这样的事情。重要的部分是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; 
    } 
} 
+0

我想我的课的消费者重写我的异常处理。在'catch(Exception e)'部分中调用IsCatchableException是明智的做法,然后让我的应用程序找出异常是否适用于它?想法是,用户总是可以实现'catch(SpecialException abc)',我的代码永远不会看到。 – LamonteCristo

1

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

+0

因此,是否正确实施了'ProcessException(e);'这样它返回一个布尔值,并且抛出发生在精确的方法中,与我的DLL? – LamonteCristo

相关问题