【问题标题】:C# best practice error handling and passing error messagesC# 最佳实践错误处理和传递错误消息
【发布时间】:2010-11-29 16:48:55
【问题描述】:

我正在使用 asp.net,我一直在努力寻找一种处理错误的简洁方法,如果有的话,将错误消息传递给用户。例如,我有一个 User 类、UserManager 类和一个 Database 类。想象一下,我想显示所有用户,显示我从 UserManager 调用 GetAllUsers 方法,它返回一个用户对象列表。此方法创建一个数据库对象并调用方法 ExecuteQuery(string query)。

编辑: 现在我的问题是,假设 ExecuteQuery() 方法出现问题(无法打开数据库)。我想在打开数据库连接时通知用户出了点问题。我应该如何做到这一点并以一种巧妙的方式处理这个问题?

编辑 2:

你会这样做吗?还是其他?

public class Database()
{
   private string _Error;

   // property error (only get)

   private void Open()
   {
     try
     {
       // Open DB
       // Fails because of error          
     }
     catch(Exception ex)
     {
       _Error = ex.Message;
     }
   }

   public DataSet ExecuteQuery(string query)
   {
      try
      {
        Open();

        // Execute query

        // return dataset
       }
       catch(Exception ex)
       {
          _Error = ex.Message;
          return null;
       }
   }
}

public class UserManager ()
{
   private string _Error;

   // Get property for Error       

   public List<User> GetAllUsers ()
   {
      Database db = new Database()

      Dataset DS = db.ExecuteQuery("my query goes here");

      (if DS == null)
      {
        _Error = db.Error;
        return null;
      }

   }
}

在用户界面中点击事件:

protected void onClick_event(args)
{

  Usermanager userman = new UserManager();
  List<User> users = userman.GetAllUsers();

  if(users == null)
  {
    // make a error panel visible
    pnlError.Visible = true;
    lblError.Text = userman.Error
  }
}

这是一个好方法吗?

【问题讨论】:

  • IMO,您应该只捕获特定异常,而不是 System.Exception。仅捕获您知道可能发生且无法阻止的异常。其他所有你应该允许冒泡的东西。
  • 我在下面编辑了我的答案,并附有一些链接供您查看。
  • @jlenbke:“冒泡”是什么意思?以及如何实现?

标签: c# asp.net .net logging error-handling


【解决方案1】:

这完全取决于您在执行查询时遇到的问题类型。这些问题可能是从没有找到记录到连接失败的任何问题。如果问题是您可以测试的问题,即缺少记录,您可以测试该问题并向您的用户显示一条消息,说明未找到记录。即使连接失败,您也应该能够对此进行测试并告诉您的用户。

对于您无法测试的问题,根据您正在编写的应用程序的类型,您可能希望让应用程序失败并使用诸如ELMAH 之类的框架记录并报告错误。

尝试这些来自我的other post 的关于此主题的链接以获取更多信息

Code Analysis Team Blog

Martin Fowler - Fail Fast

MSDN on Exception Handling

Checked vs Unchecked Exceptions

另外,this excellent article 最近发布过

【讨论】:

    【解决方案2】:

    我认为您错过了进行异常处理的正确方法。将依赖于语言/区域设置的文本存储在数据库中并不是一个好主意。该错误在它执行的上下文中也可能没有意义,方法的调用者知道它的意图,但从数据库中检索值的代码不知道代码的“更高目标”!数据库错误的描述也可能对用户根本不感兴趣,对他们来说,系统只是无法获取用户列表,仅此而已。对于开发人员来说,知道究竟出了什么问题很重要。让用户看到这一点也可能会向他们显示您不希望他们看到的数据,例如表名、密码、数据库用户名,具体取决于异常包含的内容(您无法控制)

    那么现在如何处理它:

    1. 在您处理它的地方捕获异常,即在onClick_Event
    2. 退出文件详细信息,只登录用户应该看到的页面
    3. 在你的代码(例如数据库)中遵循这个原则:

      • 不要修改对象的状态,直到明确没有任何问题可以使您的对象保持一致的状态。这意味着不要开始修改成员,然后异常来了,您必须在 finally 块中将它们全部重置为之前的状态。
      • 开始您的操作并在出现问题时抛出异常(不要在此处捕获它,毫无意义,您只会存储一条消息或整个异常以供以后检索!)
      • 成功后,将临时变量复制到对象的成员中

    这样,您将始终拥有处于一致状态和干净代码的对象。

    【讨论】:

      【解决方案3】:

      通过包装 using 语句或使用 Try/Finally 来确保释放数据库连接,因为特定类型的异常可能会给您带来麻烦。

      free book by Karl Seguin 有一章是关于异常处理的,它应该会让你很清楚。

      将异常添加到 UI 中,在那里可以根据您的样式对其进行处理。对于未处理的异常,如下所述,ELMAH 非常有用。

      【讨论】:

      • 将异常冒泡到最外点,然后您的 UI 负责根据异常类型决定向用户显示什么。除非您向抛出的异常添加更多信息,否则您应该首先捕获该异常。但老实说,看看那本书的章节,很难孤立地回答这个问题,要考虑的事情太多了。
      • 简而言之,没有。我不会在您的数据层中有任何这些尝试捕获。将它们带入您的 onclick 事件。并且由于您只是显示异常消息,因此可以应用更通用的内容。同样,这里和其他地方有很多很好的例子来说明该做什么。要问自己的一件重要事情是,为什么要在数据库层捕获异常,因为您没有向异常添加任何信息,没有做任何事情来记录它或尝试任何事情来纠正它。在这种情况下,让异常冒泡,直到你想做一些特定的事情
      • 我怎样才能冒出异常?
      【解决方案4】:

      如果您不想使用通常的 try/catch 并在 catch 中显示错误 div,那么可以使用 Page.Error event 来捕获页面上下文中的处理错误。在其中,您将调用 Server.GetLastError() 以获取最后抛出的异常,然后通过将用户引导到错误页面或显示/隐藏页面上的错误元素来通知用户出了问题。

      【讨论】:

        猜你喜欢
        • 2018-11-18
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        • 2018-09-12
        • 2017-11-26
        • 1970-01-01
        • 2016-06-06
        • 1970-01-01
        相关资源
        最近更新 更多