在我目前的项目中,我正在与一些第三方中间件进行交互,这些中间件会抛出许多不同类型的异常(大约10个或更多异常)。
我使用第三方的图书馆有一些方法,每个方法都与第三方交互,但需要保护它们不受同一组10个或更多例外的影响。
我目前所拥有的是我的图书馆的每一种方法:
try
{
// some code
}
catch (Exception1 e)
{
}
catch (Exception2 e2)
{
}
...
catch (ExceptionN eN)
{
}
异常的数量也可能会增加。
如何减少代码重复并在一个地方统一处理所有异常?
答案 0 :(得分:5)
我首先要捕获基础Exception
类型,然后使用白名单进行过滤:
try
{
// Code that might throw.
}
catch (Exception e)
{
if(e is Exception1 || e is Exception2 || e is ExceptionN)
{
// Common handling code here.
}
else throw; // Can't handle, rethrow.
}
现在,如果您想要概括过滤器,可以编写扩展名:
public static bool IsMyCustomException(this Exception e)
{
return e is Exception1 || e is Exception2 || e is ExceptionN;
}
然后你可以使用:
if(e.IsMyCustomException())
{
// Common handling code here.
}
else throw;
您可以使用一种简单的方法来概括处理程序:
private void HandleCustomException(Exception e)
{
// Common handling code here.
}
如果你想要概括整个try-catch块,你可能最好将一个委托注入一个包装操作的方法,如@vc 74所述。
答案 1 :(得分:3)
您可以使用全局异常处理程序,实现取决于您的项目类型(ASP.net - > global.asax,WPF - > App.xaml ...)
或使用以下内容:
private static void HandleExceptions(Action action)
{
try
{
action();
}
catch (Exception1 e)
{
}
catch (Exception2 e2)
{
}
...
catch (ExceptionN eN)
{
}
}
可以通过以下方式调用:
HandleExceptions(() => Console.WriteLine("Hi there!"));
如果在执行Console.WriteLine期间抛出了异常,那么它将由您的异常处理逻辑处理
请注意,要执行的代码也可能会修改外部值:
int x = 2;
HandleExceptions(() => x = 2 * x);
如果您更喜欢匿名方法:
var x = 2;
HandleExceptions(delegate()
{
x = x * 2;
});
答案 2 :(得分:1)
如何使用一个函数来处理这些异常:
try
{
//Some code here
}
catch(Exception e)
{
if(!ErrorHandler(e))
return null; //unhandled situation
}
private bool ErrorHandler(Exception e)
{
switch(e)
{
case Exception1:
//Handle the exception type here
return true;
case Exception2:
//Handle another exception type here
return true;
}
return false;
}
答案 3 :(得分:1)
我建议使用Enterprise Library 5.0异常处理块。基本上,您定义了多个异常类型,类别和处理特定异常类型的异常处理程序。理想情况下,您将定义异常类型,将其连接到格式化程序,然后使用Logging块报告异常。
答案 4 :(得分:-1)
捕获和重新抛出异常与捕获异常之间存在一些语义差异。因此,例外过滤器非常有用,因为它们允许例如过滤器。 “在IsNiceException(Ex)时捕获Ex Exception”。不幸的是,在C#程序中使用它们的唯一方法是使用DLL来包装必要的功能(DLL本身可以用vb或其他语言编写)。典型的模式可能是:
TryWhenCatchFinally( () => {trycode;}, (Exception ex) => {codeWhichReturnsTrueForExceptionsWorthCatching;}, (Exception ex) => {codeToHandleException;}, (ExceptionStatus status, Exception ex) => {finallyCode;});
“finally”代码的ExceptionStatus参数将是一个枚举,说明是否(1)没有发生异常,(2)发生了异常,但是被处理,(3)发生异常并被处理,但是另一个例外是抛出,或(4)发生异常但CodeWhichReturnsTrueForExceptionsWorthCatching返回false; (5)发生了一个异常,它没有在trycode中处理,也没有被这个块处理,但是无论如何都完成了trycode(一种罕见的情况,但它有可能发生的方式)。在第一种情况下,Ex参数将为null,并且在其他情况下包含适当的异常 - 如果在处理finally块时发生异常则可能有用的信息(抑制在finally块中发生的异常可能是坏的,但是如果在新异常转义之前,未记录或丢失早期异常,来自先前异常的所有数据通常都将丢失;如果导致先前异常的相同条件导致后一异常,则先前的异常可能包含有关内容的更多有用信息错)。
BTW,这个模式的一些注释: