2012-10-16 75 views
1

在我寫入數據庫的方法中,我處理錯誤,如下面的代碼所示。在catch (DbUpdateException ex)我想重新拋出異常並在最後的catch (Exception ex)中捕獲它。以相同的方法拋出並捕獲異常

這是可能的,以及如何做到這一點?下面的代碼不這樣做。

 using (Entities context = new Entities()) 
     { 
      try 
      { 
       context.Office.Add(office); 
       retVal = context.SaveChanges(); 
      } 
      catch (DbUpdateException ex) 
      { 
       SqlException innerException = ex.GetBaseException() as SqlException; 
       if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT) 
       { 
        throw 
         new Exception("Error ocurred"); 
       } 
       //This is momenty where exception is thrown. 
       else 
       { 
        throw ex; 
       } 
      } 
      catch (Exception ex) 
      { 
       throw 
        new Exception("Error"); 
      } 
     } 
+2

您在這裏失去了各種有用的信息。堆棧跟蹤不斷重置。 –

+2

[請不要使用流量控制異常](http://stackoverflow.com/questions/729379/why-not-use-exceptions-as-regular-flow-of-control) –

+2

你爲什麼要這樣做?你最後一次捕獲將隱藏所有的異常細節,使其更難調試和維護。如果你不打算處理這個例外,就讓它冒泡吧。 – Oscar

回答

1

你試圖嘗試築巢你try...catch塊?

using (Entities context = new Entities()) 
    { 
     try 
     { 
      try 
      { 
       context.Office.Add(office); 
       retVal = context.SaveChanges(); 
      } 
      catch (DbUpdateException ex) 
      { 
       SqlException innerException = ex.GetBaseException() as SqlException; 
       if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT) 
       { 
        throw new Exception("Error ocurred"); 
       } 
       //This is momenty where exception is thrown. 
       else 
       { 
        throw ex; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new Exception("Error"); 
     } 
    } 
8

下會更好:

context.Office.Add(office); 
retVal = context.SaveChanges(); 

讓除泡了。如果你所要做的只是重新拋棄,就不需要去捕捉東西。

注意:throw ex;將重置堆棧跟蹤 - 您想正常執行throw;。當你打電話給你的方法用try catch塊括起來

try 
{ 
    YourMethod() 
} 
catch (Exception ex) 
{ 
    throw 
     new Exception("Error"); 
} 
+2

+1,用於除草並查看此解決方案。謝謝! –

0

試試這個。因此,如果你真的需要這個功能,你需要把一個try-catch內一個try-catch的,就像這樣:

using (Entities context = new Entities()) 
{ 
    try 
    { 
     try 
     { 
      context.Office.Add(office); 
      retVal = context.SaveChanges(); 
     } 
     catch (DbUpdateException ex) 
     { 
      SqlException innerException = ex.GetBaseException() as SqlException; 
      if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT) 
      { 
       throw 
        new Exception("Error ocurred"); 
      } 
      //This is momenty where exception is thrown. 
      else 
      { 
       throw ex; 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     throw 
      new Exception("Error"); 
    } 

} 
+0

我想用同樣的方法做到這一點。 – SilverDeveloper

+1

@SilverDeveloper - 你是什麼意思?這正是你想要它做的。雖然它仍然是一個糟糕的主意。 –

1

一個try-catch只處理一個 catch塊,它們按順序計算

void YourMethod() 
{ 
using (Entities context = new Entities()) 
     { 
      try 
      { 
       context.Office.Add(office); 
       retVal = context.SaveChanges(); 
      } 
      catch (DbUpdateException ex) 
      { 
       SqlException innerException = ex.GetBaseException() as SqlException; 
       if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT) 
       { 
        throw 
         new Exception("Error ocurred"); 
       } 
       //This is momenty where exception is thrown. 
       else 
       { 
        throw ex; 
       } 
      } 
     } 
} 

然後:

+0

也謝謝你,但保羅更快。 – SilverDeveloper

+0

@SilverDeveloper,沒問題。 –

+0

但有一點需要注意的是,@Oded使得一個非常好的點和你應該考慮的事情之前,沿着嵌套try-catch塊的路徑。 –

3

如果您想從其他捕獲中捕獲異​​常,則它們不能處於同一級別。

您當前的代碼有這樣的結構:

try 
{ 
} 
catch (...) 
{ 
} 
catch (...) 
{ 
} 

您需要將其更改爲:

try 
{ 

    try 
    { 
    } 
    catch (...) 
    { 
     // throw X 
    }     
} 
catch (...) 
{ 
    // catch X here 
} 

但是,你應該非常小心,如果你真的想/需要這樣認爲。它看起來不像一個高效的錯誤處理模式。

並參見this answer爲4種不同的方式來(重新)拋出異常及其後果。

0

當你計劃你的嵌套的try-catch塊如由「保羅」知道的異常類型:

using (Entities context = new Entities())  
{   
    try 
    { 
     try 
     { 
      context.Office.Add(office); 
      retVal = context.SaveChanges(); 
     } 
     catch (DbUpdateException ex) 
     { 
      SqlException innerException = ex.GetBaseException() as SqlException; 
      if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT) 
      { 
       // this exception will be catched too in outer try-catch block <-------- 
       throw new Exception("Error ocurred"); 
      } 
      //This is momenty where exception is thrown. 
      else 
      { 
       throw ex; 
      } 
     } 
    } 
    // Catch (DbUpdateException ex) if you plan to have the rethrown exception to be catched <------------ 
    catch (Exception ex) 
    { 
     throw new Exception("Error"); 
    } 

}