良好的错误处理习惯

时间:2020-03-06 14:56:58  来源:igfitidea点击:

对于asp.net网站,什么是好的错误处理方法?例子?谢谢!

解决方案

我发现特别有用的一种做法是创建一个通用错误页面,然后将web.config的customErrors节点上的defaultRedirect设置为该错误页面。

然后设置global.asax以记录所有未处理的异常,然后将它们(未处理的异常)放在某个类的静态属性中(我有一个名为ErrorUtil的类,具有静态LastError属性)。然后,错误页面可以查看此属性,以确定向用户显示的内容。

此处有更多详细信息:http://www.codeproject.com/KB/aspnet/JcGlobalErrorHandling.aspx

与任何.net项目一样,我发现最好的方法是仅捕获特定错误类型(如果可能在给定页面上发生)。

例如,我们可以为给定输入的用户捕获格式异常(以防JavaScript验证失败且我们未使用tryparse),但始终将顶级异常的捕获留给全局错误处理程序。

try
        {
            //Code that could error here
        }
        catch (FormatException ex)
        {
            //Code to tell user of their error
            //all other errors will be handled 
            //by the global error handler
        }

我们可以使用ASP.Net的开源elmah(错误记录模块和处理程序)为我们执行此顶级/全局错误捕获。

使用elmah,它可以创建错误日志,该错误日志可通过简单配置的Web界面查看。我们还可以过滤不同类型的错误,并为不同的错误类型设置自己的自定义错误页面。

好吧,这是相当开放的,这完全是很酷的。我将带我们从Dot Net Spider下载的.doc一词,这实际上是我的小公司代码标准的基础。该标准包括一些非常有用的错误处理技巧。

一个这样的例外示例(我不记得这是文档的原始文档还是我们将其添加到文档中):
永远不要执行catch异常,什么也不做。如果隐藏异常,我们将永远不会知道该异常是否发生。我们应该始终通过编程检查所有错误条件来尝试避免异常。

不做什么的示例:

try
{
   ...
}
catch{}

除非我们有充分的理由,否则这很顽皮。

我们应该确保可以捕获应用程序生成的大多数错误,并向用户显示友好的消息。但是当然,我们无法捕获所有错误,因为可以由另一个用户使用web.config和defaultRedirect。记录错误的另一个非常方便的工具是ELMAH。 ELMAH将记录应用程序生成的所有错误,并以一种易于阅读的方式向我们显示。在应用程序中插入ELMAH就像在web.config文件中添加几行代码并添加程序集一样简单。我们绝对应该尝试一下ELMAH,它将为我们节省数小时的痛苦。

http://code.google.com/p/elmah/

  • 在每个页面中针对可能发生的异常进行防御性编码,并进行适当处理,以免每次发生异常时都不会打扰用户。
  • 记录所有异常,并提供参考。
  • 为任何未处理的异常提供一个通用错误页面,该页面提供了用于支持的参考(支持可以从日志中识别详细信息)。不要显示实际的异常,因为大多数用户不会理解该异常,但是由于它会公开有关我们系统的信息(可能是密码等),因此存在潜在的安全风险。
  • 不要捕获所有异常,不要对它们采取任何措施(如上述答案)。这样做几乎没有一个很好的理由,有时我们可能想捕获特定的异常,而不是故意进行任何操作,但是应该明智地使用它。

将用户重定向到标准错误页面并不总是一个好主意。如果用户正在处理表单,则可能不希望将其重定向到正在处理的表单之外。我将所有可能导致异常的代码放入try / catch块中,并在catch块中吐出一条警告消息,警告用户已发生错误,并将异常记录在数据库中,包括表单输入,查询字符串,等等。我正在开发内部网站,因此,大多数用户在遇到问题时都只给我打电话。对于公共站点,我们可能希望使用类似elmah的东西。

我应该尝试阻止所有内容吗?有时我不想捕获任何特定的东西,无论如何都会通过层次结构中更高级别的方法捕获错误。

如果这是主要方法,那么子方法的最佳实践是什么?

private void mainMethod()
{

  try
  {

     subMethod();
  }
  catch
  {
    //do something
  }
}

这:

private void subMethod()
{
  try{
   //code
   //code
  }
  catch
  {
    throw;
  }
}

或者这个:

private void subMethod()
{
   //code
   //code
}

public string BookLesson(Customer_Info oCustomerInfo, CustLessonBook_Info oCustLessonBookInfo)
    {
        string authenticationID = string.Empty;
        int customerID = 0;
        string message = string.Empty;
        DA_Customer oDACustomer = new DA_Customer();

        using (TransactionScope scope = new TransactionScope())
        {
            if (oDACustomer.ValidateCustomerLoginName(oCustomerInfo.CustId, oCustomerInfo.CustLoginName) == "Y")
            {
                // if a new student
                if (oCustomerInfo.CustId == 0)
                {
                    oCustomerInfo.CustPassword = General.GeneratePassword(6, 8);
                    oCustomerInfo.CustPassword = new DA_InternalUser().GetPassword(oCustomerInfo.CustPassword, false);
                    authenticationID = oDACustomer.Register(oCustomerInfo, ref customerID);
                    oCustLessonBookInfo.CustId = customerID;
                }
                else // if existing student
                {
                    oCustomerInfo.UpdatedByCustomer = "Y";
                    authenticationID = oDACustomer.CustomerUpdateProfile(oCustomerInfo);
                }
                message = authenticationID;
                // insert lesson booking details
                new DA_Lesson().BookLesson(oCustLessonBookInfo);
            }

            else
            {
                message = "login exists";
            }
            scope.Complete();
            return message;
        }

    }