2013-09-16 93 views
0
private void SetConnection(string id, string classCode) 
    { 
     try 
     { 
      _connection = new SqlConnection { ConnectionString = Settings.Default.CurrentConnection }; 
      _connection.Open(); 
      while (_connection.State == ConnectionState.Connecting || _connection.State == ConnectionState.Closed) 
       Thread.Sleep(1000); 

      _command = new SqlCommand(Settings.Default.EligibilityBenefitSP, _connection); 
      if (_command != null) _command.CommandType = CommandType.StoredProcedure; 
      _command.Parameters.Add("@ClassCode", SqlDbType.NVarChar).Value = classCode; 
      _command.Parameters.Add("@Id", SqlDbType.NVarChar).Value = id; 
     } 
     catch (Exception e) 
     { 
      throw new Exception(e.Message + " " + Settings.Default.EligibilityBenefitSP); 
     } 

    } 

    public Collection<EligibilityClassBenefit> ExtractEligibilityClassBenefit(string id, string classCode) 
    { 
     SetConnection(id, classCode); 
     Collection<EligibilityClassBenefit> eclassBene = new Collection<EligibilityClassBenefit>(); 
     SqlDataReader reader = null; 
     try 
     { 
      _command.CommandTimeout = 420; 
      if (_connection.State == ConnectionState.Open) 
       reader = _command.ExecuteReader(CommandBehavior.CloseConnection); 
      else 
       throw new Exception("Connection Closed"); 

       /* no data */ 
       if (!reader.HasRows) return null; 

       while (reader.Read()) 
       { 
        EligibilityClassBenefit eligibilityClassBenefit = new EligibilityClassBenefit 
        { 
         EffectiveDate    = reader["EffectiveDate"].ToString(), 
         EndDate      = reader["EndDate"].ToString(), 
         InitialEffectiveDate   = reader["InitialEffectiveDate"].ToString(), 
         IsAdministrativeServicesOnly = reader["IsAdministrativeServicesOnly"].ToString(), 
         EffectiveProvision   = reader["EffectiveProvision"].ToString(), 
         ProbationPeriod    = reader["ProbationPeriod"].ToString(), 
         UnderwritingType    = ExtractUnderwritingType(id), 
         ProbationPeriodUnit   = reader["ProbationPeriodUnit"].ToString(), 
         StateOfIssue     = reader["StateOfIssue"].ToString(), 
        }; 
        BenefitData benefitData = new BenefitData(); 
        eligibilityClassBenefit.Benefit = benefitData.ExtractBenefit(reader, id, classCode); 

        EligibilityClassBenefitBusinessLevelData eligibilityLevelData = new EligibilityClassBenefitBusinessLevelData(); 
        eligibilityClassBenefit.EligibilityClassBenefitBusinessLevelNodes = eligibilityLevelData.ExtractBenefitBusinessLevel(reader); 

        eclassBene.Add(eligibilityClassBenefit); 
      } 
      return eclassBene; 
     } 
     catch (Exception e) 
     { 
      throw new Exception(e.InnerException.Message + e.InnerException.StackTrace); 
     } 
     finally 
     { 
      //if (_connection.State == ConnectionState.Open) _connection.Close(); 
      if (reader != null) reader.Close(); 
      _command.Dispose(); 
     } 
    } 

上面是一个有一个普通异常的代码示例,但是当我运行这个程序时,它会随机运行一个.net运行时断开并处理异常的应用程序日志错误空引用异常。未处理的运行时错误c#

有点背景......这是一个控制台应用程序,在应用程序服务器上午夜自动运行。它针对不同的SQL Server 2008盒子执行存储过程。我们以前在执行mainenace任务时由sql server删除连接时会出现这些错误,但情况已不再如此。我需要得到一个mmore特定的错误。我不明白为什么它绕过catch子句,只是抛出未处理的运行时异常。这是什么意思?它发生在任何数量的代码点上,而不仅仅是这一点。这只是最后一次爆炸的一个例子

+1

什么捕捉你抛出的异常? –

+0

可以请你发布未处理的异常的stacktrace,但看着你的代码我认为NullReferenceException可能来自读者[****]。ToString()语句 – makim

+0

你正在捕获异常并抛出另一个异常。你能发布完整的错误消息和堆栈跟踪吗? –

回答

2

当你捕捉到异常时,你也将它们扔掉以便由调用者处理。现在,您发布的代码中没有切入点,因此很难看到此代码段外面发生了什么。

然而,冒着大胆的猜测,我对NullRef异常来源的建议就是你这样做的地方:e.InnerException.Message

InnerException属性可能为空,这将导致NullRef异常。然而,这并不是真正的例外。由于上述错误,导致程序最终进入异常处理程序的真正异常是隐藏的。

如果您想包含来自InnerException的消息,请首先检查它是否为null。

编辑:

这样做:

catch (Exception e) 
{ 
    throw new Exception(e.InnerException.Message + e.InnerException.StackTrace); 
} 

捕捉任何异常,并重新抛出出来进行处理。如果调用代码没有处理异常,即不将调用包装在try-catch块中,则该异常将被视为运行时未处理。

实际上,根本没有意义去做你正在做的事情。除非你打算对问题做些什么,否则不要捕获异常。你在这里做的只是搞乱了调用者的StackTrace,因为你正在重新抛出一个新的异常。如果你觉得你必须削减和重新抛出出于某种原因,你应该这样做:

catch (Exception e) 
{ 
    throw new Exception("I have a good reason for interrupting the flow", e); 
} 

注意异常实例在构造函数重新抛出异常过去了。这将最终成为内在的例外。

关于您的例外策略,这也是非常必要:

if (_connection.State == ConnectionState.Open) 
    reader = _command.ExecuteReader(CommandBehavior.CloseConnection); 
else 
    throw new Exception("Connection Closed"); 

ExecuteReader方法已经抛出InvalidOperationException如果连接是关闭的,这是不是你的Exception扔更加具体。如果您打算为此做些什么,请稍后再查看更具体的例外情况。现在,你使用异常作为你的程序逻辑的一部分,这是不好的做法。

+0

我承认你的观点,但是当我没有发送内部异常时它仍然会抛出。 – rigamonk

+0

感谢您的耐心等待。它被包装在try/catch中的main()方法调用。它适用于正常错误的情况,但是在午夜发生的这些错误总是以未处理的方式发生。我没有看到这个 – rigamonk

+0

你需要发布该代码以便我们能够帮助你。您需要阅读异常处理并更加小心NullRef。例如,看看Resharper,它是一个插件,可以帮助您在设计时发现NullRefs。 –

相关问题