2013-03-17 67 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