C#最佳实践错误处理和传递错误消息

时间:2009-09-19 07:22:22

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

我正在使用asp.net,我总是在努力寻找一种处理错误的简洁方法,如果有的话,将错误消息传递给用户。例如,我有一个User类,UserManager类和一个Database类。 Imagina我想显示所有用户,显示我从UserManager调用方法GetAllUsers返回User对象列表。此方法创建一个Database对象并调用方法ExecuteQuery(字符串查询)。

编辑: 现在我的问题,想象一下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
  }
}

这是一个好方法吗?

4 个答案:

答案 0 :(得分:3)

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

对于无法测试的问题,根据您编写的应用程序类型,您可能希望让应用程序失败并使用某些框架(如ELMAH日志)并报告错误。

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

Code Analysis Team Blog

Martin Fowler - Fail Fast

MSDN on Exception Handling

Checked vs Unchecked Exceptions

此外,最近发布了this excellent article

答案 1 :(得分:3)

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

现在如何处理它:

  1. 抓住处理它的异常,即onClick_Event
  2. 注销文件详细信息,仅显示用户应该看到的页面
  3. 在您的代码中(例如,数据库)遵循以下原则:

    • 在明确没有任何问题可以使对象保持一致状态之前,请不要修改对象的状态。这意味着不要开始修改成员,然后异常来了,你必须将它们全部重置为finally块中的先前状态。
    • 开始你的操作并对问题抛出异常(不要在这里抓住它,没有意义,你只需存储一条消息或整个异常以便以后检索!)
    • 成功时,将临时变量复制到对象的成员
  4. 这样,您将始终拥有一致状态和干净代码的对象。

答案 2 :(得分:2)

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

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

将异常冒泡到UI,根据你的风格可以处理它。对于未处理的异常,如下所述,ELMAH非常有用。

答案 3 :(得分:1)

如果您不想使用通常的try / catch并在catch中显示错误div,则可以使用Page.Error event来捕获页面上下文中的句柄错误。在其中,您将调用Server.GetLastError()以获取抛出的最后一个异常,然后通过将它们指向错误页面或通过在页面上显示/隐藏错误元素来通知用户出错。