2013-03-17 76 views
0

解釋我的問題,最好的辦法是用下面的僞代碼:如何從一個異常處理程序轉到另一個異常處理程序?

try 
{ 
    //Do work 
} 
catch (SqlException ex) 
{ 
    if (ex.Number == -2) 
    { 
     debugLogSQLTimeout(ex); 
    } 
    else 
    { 
     //How to go to 'Exception' handler? 
    } 
} 
catch (Exception ex) 
{ 
    debugLogGeneralException(ex); 
} 
+0

爲什麼不只'debugLogGeneralException(ex);代替你的評論? – 2013-03-17 06:37:52

+0

@romanm:正如我所說的,它只是一個僞代碼,在我的實例中這不是一個真正的函數。 – c00000fd 2013-03-17 06:38:41

+1

我要說的是你應該把你的「異常處理程序」邏輯代替你的評論,而不是「去」那裏 – 2013-03-17 06:43:11

回答

3
Exception ex = null; 
try 
{ 
    //Do work 
} 
catch (SqlException sqlEx) 
{ 
    ex = sqlEx; 
    if (ex.Number == -2) 
    { 
     //.. 
    } 
    else 
    { 
     //.. 
    } 
} 
catch (Exception generalEx) 
{ 
    ex = generalEx; 
} 
finally() 
{ 
    if (ex != null) debugLogGeneralException(ex); 
} 
+0

+1!我也在想同樣的事情! – 2013-03-17 06:42:43

+0

非常好。我希望得到一些'rethrow'命令,但這也會起作用。 – c00000fd 2013-03-17 06:48:40

1

第一catch子句相匹配的是,可以在同一try塊上可能運行的唯一的一個。

我能想到的做你嘗試什麼,最好的辦法是包括在更普遍的類型轉換和條件:

try 
{ 
    //Do work 
} 
catch (Exception ex) 
{ 
    var sqlEx = ex as SqlException; 
    if (sqlEx != null && sqlEx.Number == -2) 
    { 
     debugLogSQLTimeout(ex); 
    } 
    else 
    { 
     debugLogGeneralException(ex); 
    } 
} 

如果你發現自己在整個數據寫這一遍又一遍層,至少花時間將其封裝在一個方法中。

+0

非常好。我不知道可以拋出這樣的例外。它不會引發它自己的例外,是嗎? (假設它是算術溢出異常) – c00000fd 2013-03-17 23:54:23

+0

在這種情況下,考慮到我們將sqlEx.Number與一個常量值進行比較(我可能會在生產代碼中聲明一個'const'),所以我沒有認爲存在爆發未處理的異常的真正風險。 – 2013-04-08 07:12:05

+0

嗯......現在我明白你的問題......我想。不,如果將另一種類型的異常轉換爲另一種類型的過程將不會以某種方式觸發重新引發該異常。你必須拋出()它才能發生。 – 2013-05-19 23:47:41

0

我不相信有什麼辦法可以做到這一點,因爲catch塊在不同的範圍。在沒有退出try塊的情況下無法重新拋出,也無法「調用」最終catch塊,因爲它只在異常期間被觸發。

我會建議一樣的羅馬米以上,只是作出相同的呼叫。否則,你必須做一些非常糟糕的事情。像下面的瘋狂的代碼,你永遠不應該使用,但我包括,因爲它做了像你想要的東西。

一般來說,我認爲你所做的是通過異常來控制正常流量,這是不推薦的。如果你想追蹤超時,你可能應該以另一種方式處理。

請注意,您可以像下面的代碼一樣使用goto語句的錯誤,但我將其包含在內,因此沒有人可以忘記這是一個壞主意。 =)

void Main() 
{ 
    Madness(new NotImplementedException("1")); //our 'special' case we handle 
    Madness(new NotImplementedException("2")); //our 'special' case we don't handle 
    Madness(new Exception("2")); //some other error 
} 

void Madness(Exception e){ 
    Exception myGlobalError; 

    try 
    { 
     throw e; 
    } 
    catch (NotImplementedException ex) 
    { 
     if (ex.Message.Equals("1")) 
     { 
      Console.WriteLine("handle special error"); 
     } 
     else 
     { 
      myGlobalError = ex; 
      Console.WriteLine("going to our crazy handler"); 
      goto badidea; 
     } 
    } 
    catch (Exception ex) 
    { 
     myGlobalError = ex; 
     Console.WriteLine("going to our crazy handler"); 
     goto badidea; 
    } 
    return; 

    badidea: 
    try{ 
     throw myGlobalError; 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine("this is crazy!"); 
    } 
} 
// Define other methods and classes here 
+0

是的,你是對的,這是一個瘋狂的想法)) – c00000fd 2013-03-17 23:53:19

+0

=)我希望確保它足夠瘋狂,沒有人會真正使用它。我同意羅曼米對原始代碼的評論。不管你做什麼,你仍然會做一些真正瘋狂的事情。即使try/catch/finally也會導致您進行空檢查,無論每個調用try/catch/finally的單個操作發生錯誤。可能不是很多開銷,但它是一些東西。沒有給出的答案實際上是「去」另一個異常處理程序,因爲你不能。 – 2013-03-18 15:24:01