我应该把try catch放在哪里?

时间:2014-12-10 09:39:25

标签: c# .net exception-handling try-catch

学习记录错误。 这是我项目中代码的基本结构。

我被告知try块必须只放在事件处理程序中。 但是在记录错误时,需要知道哪种方法导致了错误。 所以,在这种情况下,我是否应该继续AllIsFine()& SaveData()。    如果是,那么它应该记录错误还是throw

什么是最佳/标准做法。

DataContext objDataContext = new DataContext();
protected void btn_Click(object sender, EventArgs e)
{
  try
   {
     if(AllIsFine())
      {
        objDataContext.SaveData();
      }
   }
  catch(Exception ex)
   {
     //some handling
   }
}

private bool AllIsFine()
{
   //some code
}

编辑:当然,我们会尝试看到它永远不会引发异常,但却不实用。我这样看着它。部署时,我唯一的访问权限就是日志,并且需要尽可能多地获取信息。所以在这种情况下,(并且使用这种结构),你建议在哪里保留try catch

4 个答案:

答案 0 :(得分:6)

  

我被告知try块必须只放在Event中   处理

事实并非如此 有不同类型的例外,一些你需要处理,一些你应该抛出,一些你应该抓住,一些你不应该。请阅读this

要点:

  • 你应该抓住可以用它们做点什么的例外
  • 如果您只想记录例外捕获,记录,然后使用throw而不是throw ex(它会重置调用堆栈)
  • 如果可以,防止发生异常,检查阻止异常的条件(IndexOutOfRangeExceptionNullPointerExceptionArgumentNullException),而不是执行操作并捕获异常
  
      
  • 不要抓住致命的例外;无论如何你无能为力,并试图让它变得更糟。
  •   
  • 修复你的代码,使其永远不会触发一个愚蠢的异常 - 一个"索引超出范围"生产代码中绝不应发生异常。
  •   
  • 尽可能通过调用那些引入非异常的烦恼方法的“尝试”版本来避免烦恼的异常   情况。如果你不能避免调用一个令人烦恼的方法,赶上它   令人烦恼的例外。
  •   
  • 始终处理表示意外外生条件的异常;一般来说,预期是不值得或不实际的   每一次可能的失败试试操作并做好准备   处理异常。
  •   

答案 1 :(得分:2)

try-catch语句包含一个try块,后跟一个或多个catch子句,这些子句为不同的异常指定处理程序。

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

可以在同一个try-catch语句中使用多个特定的catch子句。可以在catch块中使用throw语句来重新抛出catch语句捕获的异常。您可以捕获一个异常并抛出不同的异常。执行此操作时,请将您捕获的异常指定为内部异常

catch (FileNotFoundException ex)
{
    // FileNotFoundExceptions are handled here.
}
catch (InvalidCastException ex) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", ex);
}

throw ex;基本上就像从那一点抛出一个异常,因此堆栈跟踪只会发送到你发出throw ex;语句的位置

答案 2 :(得分:2)

  

但是在记录错误时,需要知道哪种方法   导致错误。

你应该使用调用堆栈。

尽可能多地尝试防止异常,而不是捕获它们,如果你想捕获一个错误,尝试捕获一个特定的错误,我的意思是,不要尝试捕获异常,而是像InvalidCastException那样具体。

捕获错误后,您应该记录异常,但不要抛出异常来记录它。

答案 3 :(得分:1)

我想了一会儿你的问题,即使已经回答了,我想分享一下我的想法。

一般

在谈论异常处理时,您必须记住的异常: 当代码无法按预期运行时,会发生异常,从而导致应用程序的行为/状态不一致。 这个想法引导我们做出一个重要规则:捕获您无法处理的异常! Exception系统提供安全性。考虑连接到数据库的会计软件,连接会引发异常。如果您只记录异常并且没有向用户提供任何关于此的通知,他将开始使用该软件,当他尝试保存时,数据将丢失!

你知道, 处理异常非常重要:

  • 其中一些将由用户处理(通常在UI层 - 例如MVVM / MVC中的视图),例如示例中的数据库异常 - 只有用户可以决定是否需要数据库,连接字符串已更改或者如果重试将解决问题。
  • 其他人可以在发生的地方进行处理;例如,与某种硬件交互的代码通常使用某种重试或断路器逻辑来实现方法。

架构

决定也受到架构的影响: 让我们回到数据库异常场景:您无法在UI层中处理特定的异常,例如MySQL特定的异常(MySqlException),因为这会导致从View层到特定的Model层实现和分层架构的边界将被打破。但是,这不是主题,因为您的问题是关于记录异常,但是您应该牢记这一点,并且可能会这样考虑:捕获具体库的异常或属于特定层/依赖项的异常发生和记录他们和 throw new ,更通用(可能是自创)的例外。这些异常可以在视图层中处理并呈现给用户。

实施

的问题也很重要。由于伐木被视为一个跨领域的问题。您可以考虑一个AOP框架,或者正如我在评论中建议的那样,使用装饰器模式。您可以通过控制使用的基本反转来组成日志记录装饰器,并且通过将所有内容包装在try-catch块中,您的代码将更加清晰。 如果您在应用程序中使用(或计划使用)DI容器,您还可以使用拦截,这将允许您通过指定的行为动态包装方法调用(如try-catch)。

摘要

处理您可以处理它们的异常,并记录它们,从中获取最相关的数据(例如上下文)来重现错误。但请记住,异常是一种安全机制 - 它会在应用程序不再处于安全状态时停止它 - 当您不转发异常时(使用throw)并只记录它们,这可能导致不是最好的用户体验。

如果您想要任何代码示例,只需要求它们;)